Подтвердить что ты не робот

Как заставить SSLEngine использовать TLSv1.2 на Android (4.4.2)?

Люди, я надеюсь, что там что-то очевидное, что мне не хватает, и я надеюсь, что кто-то сможет пролить свет. Я пытаюсь запустить TLSv1.2 в контексте SSL + NIO (используя AndroidAsync), поэтому я пытаюсь чтобы включить его через SSLEngine. Я могу запустить код следующим образом:

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, null);
        String[] protocols = sslContext.getSupportedSSLParameters().getProtocols();
        for (String protocol : protocols) {
            Timber.d("Context supported protocol: " + protocol);
        }

        SSLEngine engine = sslContext.createSSLEngine();
        String[] supportedProtocols = engine.getSupportedProtocols();
        for (String protocol : supportedProtocols) {
            Timber.d("Engine supported protocol: " + protocol);
        }

И в итоге я вижу это на logcat:

06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: SSLv3
06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.2
06-22 21:56:27.735    1117-1117/? D/XXX﹕ Engine supported protocol: TLSv1
06-22 21:56:27.745    1117-1117/? D/XXX﹕ Engine supported protocol: SSLv3

Конечно, если я пытаюсь engine.setEnabledProtocols(new String[] { "TLSv1.2" }) получить исключение IllegalArgumentException, то протокол TLSv1.2 не поддерживается.

Я вижу контекстные утверждения для поддержки TLSv1.2, но тогда движок, который я делаю из этого контекста, не работает? Что здесь происходит? Ничего из этого не изменится, если я использую "TLS" вместо "TLSv1.2" в первой строке выше, btw.

Я понимаю, что это может иметь какое-то отношение к этой проблеме, и я прочитал этот (еще не отвеченный) вопрос и статьи, подобные этому, но они, похоже, не попадают в точку - решения Я видел, что все, похоже, полагаются на SSLSocket, а не на SSLEngine.

Большое спасибо за любые знания, которые вы можете потерять.

ОБНОВЛЕНИЕ 6/23/14 10AMEDT

Итак, я нашел SSLEngine.setSSLParameters, который, я надеялся, позволил мне передать SSLParameters, который я получил из SSLContext.getSupportedSSLParameters(), но когда я вызываю это, я получаю исключение, которое утверждает, что набор шифров не поддерживается, поэтому он похоже, что setSSLParameters() делает то же самое, что и setEnabledCipherSuites(), и движок уже находится в состоянии, когда он не распознает протокол/пакеты TLS 1.2 как поддерживаемый.

4b9b3361

Ответ 1

Документы Android API правильно указывают, что TLSv1.2 поддерживается только для SSLEngine в API уровня 20 или более поздней версии (Lollipop), в то время как SSLSocket поддерживает его начиная с уровня 16.

Использование SSLSocket или требование API 20 не было вариантом для нашего проекта, и ни один из них не менял код сервера, чтобы разрешить TLSv1 или SSLv3. Нашим решением было установить более нового поставщика безопасности, используя Службы Google Play:

    ProviderInstaller.installIfNeeded(getApplicationContext());

Это эффективно дает вашему приложению доступ к более новой версии OpenSSL и Java Security Provider, которая включает поддержку TLSv1.2 в SSLEngine. Как только новый провайдер установлен, вы можете создать SSLEngine, который поддерживает SSLv3, TLSv1, TLSv1.1 и TLSv1.2 обычным способом:

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    SSLEngine engine = sslContext.createSSLEngine();

Или вы можете ограничить разрешенные протоколы с помощью engine.setEnabledProtocols.

Ответ 2

Вот как это сделать с AndroidAsync:

ProviderInstaller.installIfNeeded(context);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(KeyManager[] km, TrustManager[] tm, SecureRandom rm);
SSLEngine engine = sslContext.createSSLEngine();
AsyncHttpClient.getDefaultInstance().insertMiddleware((AsyncHttpClientMiddleware) engine); 

Обновление SSLEngine и вставка его в качестве промежуточного программного обеспечения в AndroidAsync, похоже, работает.

Ответ 3

Попробуйте это решение, если вы используете okHttp. Решение для включения TLSv1.2 на Android 4.4

Была ли та же проблема на Android < 5,0 (16 <= API < 20). Благодаря вашим сообщениям я смог сделать эту работу, поэтому для тех, кто попадает сюда, это готовое решение. На момент написания этой статьи я использую OkHttp 3.4.1.

Теги: невозможно найти приемлемые протоколы, javax.net.ssl.SSLProtocolException: SSL-рукопожатие отменено: