versión verified una type studio servidor protocolo network enabled conjunto conexion común cliente cifrado check certificado admiten java android ssl

java - verified - HTTPS GET(SSL) con Android y certificado de servidor autofirmado



retrofit ssl pinning (7)

He revisado varias publicaciones sobre cómo recuperar algo a través de HTTPS en Android, desde un servidor que usa un certificado autofirmado. Sin embargo, ninguno de ellos parece funcionar; todos fallan en eliminar el

javax.net.ssl.SSLException: mensaje de certificado de servidor no confiable.

No es una opción modificar el servidor para que tenga un certificado confiable, y tampoco es una opción hacer que el certificado del servidor coincida con la dirección IP del servidor.

Tenga en cuenta que el servidor no tendrá un nombre DNS, solo tendrá una dirección IP. La solicitud GET se ve así:

https://username:password@anyIPAddress/blabla/index.php?param=1&param2=3

Soy plenamente consciente de que esta solución es propensa a ataques de hombre en el medio, etc.

Por lo tanto, la solución debe ignorar la falta de confianza en el certificado e ignorar la falta de coincidencia del nombre de host.

¿Alguien sabe el código, que hace esto, usando Java para Android?

Hay muchos intentos de explicar esto en stackoverflow.com , y muchos fragmentos de código, pero parece que no funcionan, y nadie ha proporcionado un bloque de código que resuelva esto, hasta donde puedo ver. Sería interesante saber si alguien realmente resolvió esto, o si Android simplemente bloquea certificados que no son de confianza.


Como señala correctamente, hay dos problemas: a) el certificado no es de confianza, yb) el nombre en el certificado no coincide con el nombre de host.

ADVERTENCIA: para cualquier otra persona que llegue a esta respuesta, este es un truco sucio y horrible y no debe usarlo para nada que importe. SSL / TLS sin autenticación es peor que ningún cifrado en absoluto: leer y modificar sus datos "encriptados" es trivial para un atacante y ni siquiera sabría que estaba sucediendo .

¿Aún conmigo? Temía que sí ...

a) se resuelve creando un SSLContext personalizado cuyo TrustManager acepta algo:

SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[] { new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) {} public void checkServerTrusted(X509Certificate[] chain, String authType) {} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }, null); HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

y b) creando un HostnameVerifier que permite que la conexión continúe aunque el certificado no coincida con el nombre de host:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } });

Ambos deben suceder justo al comienzo de su código, antes de empezar a jugar con HttpsURLConnections, etc. Esto funciona tanto en Android como en el JRE regular. Disfrutar.





Si está utilizando un HttpsURLConnection, intente llamar a setHostnameVerifier antes de connect() y pasarle un HostnameVerifier que solo acepta independientemente de la veracidad.