¿Hacer que SSLEngine use TLSv1.2 en Android(4.4.2)?
(3)
Amigos, espero que haya algo obvio que me esté perdiendo, y espero que alguien pueda arrojar algo de luz. Estoy tratando de hacer que TLSv1.2 se ejecute en un contexto SSL + NIO (usando la biblioteca AndroidAsync ), así que estoy tratando de habilitarlo a través de un SSLEngine. Puedo ejecutar código como este:
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);
}
Y termino viendo esto en 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
Por supuesto, si trato de engine.setEnabledProtocols(new String[] { "TLSv1.2" })
obtengo una IllegalArgumentException "El protocolo TLSv1.2 no es compatible".
Puedo ver las reclamaciones de contexto para admitir TLSv1.2, pero el motor que hago de ese contexto no lo hace. ¿Que está pasando aqui? Nada de esto cambia si uso "TLS" en lugar de "TLSv1.2" en la primera línea de arriba, por cierto.
Supongo que esto podría tener algo que ver con este problema , y he leído esta pregunta (aún sin respuesta) y artículos como este , pero parece que no están acertando, las soluciones que he visto parecen haber aparecido. confíe en SSLSocket en lugar de SSLEngine.
Muchas gracias por cualquier conocimiento que puedas dejar.
ACTUALIZACIÓN 6/23/14 10AMEDT
Así que encontré SSLEngine.setSSLParameters
, que esperaba que me permitiera pasar un SSLParameters que obtuve de SSLContext.getSupportedSSLParameters()
, pero cuando llamo recibo una excepción que afirma que las suites de cifrado no son compatibles, por lo que parece al igual que setSSLParameters () solo hace lo mismo que setEnabledCipherSuites (), y el motor ya está en un estado en el que no reconoce el protocolo / suites TLS 1.2 como compatible.
Aquí es cómo hacer con 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);
La actualización de SSLEngine y su inserción como middleware en AndroidAsync parece funcionar.
Los documentos de la API de Android indican correctamente que TLSv1.2 solo es compatible con SSLEngine en el nivel 20 de API o posterior (Lollipop), mientras que SSLSocket lo admite desde el nivel 16.
Usar SSLSocket o requerir API 20 no era una opción para nuestro proyecto y ninguno de los dos estaba cambiando el código del servidor para permitir TLSv1 o SSLv3. Nuestra solución fue instalar un nuevo proveedor de seguridad utilizando los servicios de Google Play :
ProviderInstaller.installIfNeeded(getApplicationContext());
Esto le da a su aplicación acceso a una versión más reciente de OpenSSL y Java Security Provider que incluye soporte para TLSv1.2 en SSLEngine. Una vez que se instala el nuevo proveedor, puede crear un SSLEngine que admita SSLv3, TLSv1, TLSv1.1 y TLSv1.2 de la manera habitual:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
SSLEngine engine = sslContext.createSSLEngine();
O puede restringir los protocolos habilitados usando engine.setEnabledProtocols
.
Pruebe esta solución si está usando okHttp. Solución para habilitar TLSv1.2 en Android 4.4
Tenía el mismo problema en Android <5.0 (16 <= API <20). Gracias a sus publicaciones, pude hacer que esto funcionara, por lo que para cualquiera que llegue, esta es la solución lista para usar. En el momento de escribir este artículo, estoy usando OkHttp 3.4.1.
Etiquetas: No se pueden encontrar los protocolos aceptables, javax.net.ssl.SSLProtocolException: Se canceló el protocolo SSL: