Estoy intentando ejecutar el siguiente código en Android
URLConnection l_connection = null;
// Create connection
uzip=new UnZipData(mContext);
l_url = new URL(serverurl);
if ("https".equals(l_url.getProtocol())) {
System.out.println("<<<<<<<<<<<<< Before TLS >>>>>>>>>>>>");
sslcontext = SSLContext.getInstance("TLS");
System.out.println("<<<<<<<<<<<<< After TLS >>>>>>>>>>>>");
sslcontext.init(null,
new TrustManager[] { new CustomTrustManager()},
new java.security.SecureRandom());
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomHostnameVerifier());
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext
.getSocketFactory());
l_connection = (HttpsURLConnection) l_url.openConnection();
((HttpsURLConnection) l_connection).setRequestMethod("POST");
} else {
l_connection = (HttpURLConnection) l_url.openConnection();
((HttpURLConnection) l_connection).setRequestMethod("POST");
}
/*System.setProperty("http.agent", "Android_Phone");*/
l_connection.setConnectTimeout(10000);
l_connection.setRequestProperty("Content-Language", "en-US");
l_connection.setUseCaches(false);
l_connection.setDoInput(true);
l_connection.setDoOutput(true);
System.out.println("<<<<<<<<<<<<< Before Connection >>>>>>>>>>>>");
l_connection.connect();
Encendido l_connection.connect()
, está dando esta SSLhandshakeException. A veces funciona, pero la mayoría de las veces da la excepción. Solo está sucediendo en el emulador de Android 4.0. Lo probé en Android 4.4 y 5.0, funciona bien. Cuál podría ser la causa de esto ? Por favor ayuda
STACKTRACE
04-28 15:51:13.143: W/System.err(2915): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.143: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.util.InitiateRMS$2.run(InitiateRMS.java:221)
04-28 15:51:13.153: W/System.err(2915): at java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153: W/System.err(2915): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.153: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153: W/System.err(2915): ... 11 more
04-28 16:42:44.139: W/ResourceType(3140): No package identifier when getting value for resource number 0x00000000
android
ssl
sslhandshakeexception
android-4.0.3-ice-cream-sandwich
Bhavit S. Sengar
fuente
fuente
Respuestas:
Encontré la solución analizando los paquetes de datos usando wirehark. Lo que encontré es que mientras hacía una conexión segura, Android estaba recurriendo a SSLv3 desde TLSv1 . Es un error en las versiones de Android <4.4 y se puede resolver eliminando el protocolo SSLv3 de la lista de Protocolos habilitados. Hice una clase socketFactory personalizada llamada NoSSLv3SocketFactory.java. Use esto para hacer un socketfactory.
Use esta clase así mientras se conecta:
ACTUALIZAR:
Ahora, la solución correcta sería instalar un proveedor de seguridad más nuevo utilizando Google Play Services :
Esto efectivamente 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 forma habitual:
O puede restringir los protocolos habilitados usando
engine.setEnabledProtocols
.No olvide agregar la siguiente dependencia ( verifique la última versión aquí ):
Para obtener más información, consulte este enlace .
fuente
Guión
Recibía excepciones de SSLHandshake en dispositivos que ejecutan versiones de Android anteriores a Android 5.0. En mi caso de uso, también quería crear un TrustManager para confiar en mi certificado de cliente.
Implementé NoSSLv3SocketFactory y NoSSLv3Factory para eliminar SSLv3 de la lista de protocolos compatibles de mi cliente, pero no pude hacer que ninguna de estas soluciones funcionara.
Algunas cosas que aprendí:
Que funciono para mi
Permita que la seguridad de Android se
Provider
actualice al iniciar su aplicación.El proveedor predeterminado antes de 5.0+ no deshabilita SSLv3. Siempre que tenga acceso a los servicios de Google Play, es relativamente sencillo parchear el proveedor de seguridad de Android desde su aplicación.
Si ahora crea su OkHttpClient o HttpURLConnection, TLSv1.1 y TLSv1.2 deberían estar disponibles como protocolos y SSLv3 debería eliminarse. Si el cliente / conexión (o más específicamente es SSLContext) se inicializó antes de llamar
ProviderInstaller.installIfNeeded(...)
, será necesario volver a crearlo.No olvide agregar la siguiente dependencia (la última versión se encuentra aquí ):
Fuentes:
Aparte
No necesitaba establecer explícitamente qué algoritmos de cifrado debería usar mi cliente, pero encontré una publicación de SO que recomendaba los que se consideraban más seguros en el momento de escribir este artículo: ¿Qué suites de cifrado habilitar para SSL Socket?
fuente
Además, debe saber que puede forzar TLS v1.2 para dispositivos Android 4.0 que no lo tienen habilitado de forma predeterminada:
Coloque este código en onCreate () de su archivo de aplicación :
fuente
Anteriormente, también resolví este problema con la
SSLFactory
implementación personalizada , pero de acuerdo con los documentos de OkHttp, la solución es mucho más fácil.Mi solución final con los
TLS
cifrados necesarios para dispositivos 4.2+ se ve así:Tenga en cuenta que el conjunto de protocolos admitidos depende de la configuración de su servidor.
fuente
Encontré la solución aquí en este enlace .
Solo tiene que colocar el siguiente código en su clase de aplicación de Android. Y eso es suficiente. No es necesario realizar ningún cambio en la configuración de la modificación. Me salvó el día.
Espero que esto sea de ayuda. Gracias.
fuente
Esto me lo resolvió:
Android 4.1. habilitar tls1.1 y tls 1.2
fuente
También tengo este problema con el informe de error. Mi código está debajo.
Tengo mi Springboot como backend y uso Android OKHttp para obtener información. El error crítico que cometí fue que utilizo un .url ( "https : //10.0.2.2: 8010 / getShopInfo / aaa") en el código de Android. Pero mi backend no puede solicitar https. Después de usar .url (" http : //10.0.2.2: 8010 / getShopInfo / aaa") , mi código salió bien. Entonces, quiero decir que mi error no es la versión del emulador, sino el protocolo de solicitud. Me encuentro con otro problema después de hacer lo que dije, pero es otro problema, y adjunto el método de resolución del nuevo problema .
¡Buena suerte, CHICO!
fuente
Fue reproducible solo cuando uso proxy en genymotion (<4.4).
Verifique la configuración de su proxy en Configuración-> Conexiones inalámbricas y redes-> WiFi -> (Mantenga presionado WiredSSID) -> Modificar red
Seleccione mostrar opciones avanzadas: establezca la configuración de proxy en NINGUNO.
fuente
Cuando recibí este error, fue porque los protocolos (versiones TLS) y / o los conjuntos de cifrado admitidos por el servidor no estaban habilitados en el dispositivo (y posiblemente ni siquiera los admitiera). Para API 16-19, TLSv1.1 y TLSv1.2 son compatibles pero no están habilitados de forma predeterminada. Una vez que los habilité para estas versiones, seguí recibiendo el error porque estas versiones no admiten ninguno de los cifrados en nuestra instancia de AWS CloudFront.
Como no es posible agregar cifrados a Android, tuvimos que cambiar nuestra versión de CloudFront de TLSv1.2_2018 a TLSv1.1_2016 (que todavía admite TLSv1.2; simplemente no lo requiere), que tiene cuatro de los cifrados compatibles con las versiones anteriores de Android, dos de las cuales todavía se consideran fuertes.
En ese momento, el error desapareció y las llamadas se realizaron (con TLSv1.2) porque había al menos un protocolo y al menos un cifrado que compartían el dispositivo y el servidor.
Referirse a las tablas de esta página para ver qué protocolos y cifrados son compatibles y están habilitados en qué versiones de Android.
¿Estaba realmente Android tratando de usar SSLv3 como implica la parte del mensaje de error "falla en el protocolo de enlace de alerta sslv3"? Lo dudo; Sospecho que se trata de una vieja telaraña en la biblioteca SSL que no se ha limpiado, pero no puedo asegurarlo.
Para habilitar TLSv1.2 (y TLSv1.1), pude usar uno mucho más simple
SSLSocketFactory
que los que se ven en otros lugares (comoNoSSLv3SocketFactory
). Simplemente se asegura de que los protocolos habilitados incluyan todos los protocolos admitidos y que los cifrados habilitados incluyan todos los cifrados admitidos (este último no era necesario para mí, pero podría serlo para otros); consulteconfigure()
la parte inferior. Si prefiere habilitar solo los protocolos más recientes, puede reemplazarlossocket.supportedProtocols
con algo comoarrayOf("TLSv1.1", "TLSv1.2")
(lo mismo para los cifrados):fuente
Resolví el problema con esto: NoSSLv3SocketFactory.java
Clase principal :
fuente
Mi respuesta se acerca a las respuestas anteriores, pero debe escribir la clase exactamente sin cambiar nada.
}
y usarlo con HttpsURLConnection
fuente