Как заставить 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» в первой строке выше, кстати.

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

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

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

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

    В документах 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 .

    Вот как это сделать с 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, похоже, сработает.

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

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

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