Pregunta Recepción de SSLHandshakeException: falla de handshake a pesar de que mi cliente ignora todos los certs


Tengo un programa Java que se conecta a un servidor web usando SSL / TLS, y envía varias solicitudes HTTP a través de esa conexión. El servidor es localhost y está utilizando un certificado autofirmado, pero mi código usa TrustManagers personalizados e ignora los certificados no válidos. Ha funcionado perfectamente hasta ahora.

La única diferencia en el servidor es que solía ejecutar jboss 6 y ahora está ejecutando jboss 7. No estoy seguro de si esto es un problema de configuración, o si hay un problema con mi código, pero obtengo los mismos errores si Intento conectarme utilizando otros programas basados ​​en Java como WebScarab o ZAP.

En cualquier caso, ¿hay algo que pueda hacer con mi código para evitar este problema? Aquí está el error completo:

Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)

Aquí están los mensajes de depuración antes de la falla:

main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure

19
2018-03-22 18:35


origen


Respuestas:


Entonces encontré el problema. Puede haber un error en Java, pero el cliente parece iniciar un protocolo de enlace TLSv1, pero luego envía un mensaje de saludo de cliente SSLv2, en cuyo punto el servidor rechaza la conexión.

Esto sucede incluso si crea su SSLContext con una instancia de TLS:

SSLContext sslContext = SSLContext.getInstance("TLS");

La solución es establecer una propiedad del sistema antes de realizar cualquier intento de conexión:

System.setProperty("https.protocols", "TLSv1");

Probablemente haya otras soluciones, pero esta funcionó para mí.


25
2018-03-23 10:37



La información que proporcionas es muy pequeña y también tu rastro de pila.
Voy a adivinar aquí.
Lo que sospecho es que en el nuevo servidor, el protocolo es TLSv1, mientras que los clientes intentan conectarse con SSLv3 (o menos) y, como resultado, falla el protocolo de enlace.

Cambia tus clientes para usar una versión más alta de TLS o
Haga que su servidor web sea compatible con SSLv3 también. Sé cómo hacer esto en Tomcat pero no en JBoss.

Si esto no funciona, actualice la publicación con más información (y un seguimiento completo de la pila).
Debe habilitar la información de depuración de ssl -Djavax.net.debug=ssl 


4
2018-03-22 22:14



¿Esto se resolvió alguna vez?

Tenía exactamente el mismo problema, esencialmente estaba recibiendo una excepción de saludo inmediatamente después del clienteHola. Entonces, la cadena de eventos era

  1. Presentaría mi certificado al servidor
  2. Servidor respondería inmediatamente con una falla de apretón de manos. (Ni siquiera volvería a recibir un servidor Hola).

Finalmente, descubrí que el servidor requería un algoritmo de cifrado / descifrado más sólido que el que yo estaba suministrando en la fase inicial de handshake (es decir, el cliente y el servidor no podían ponerse de acuerdo sobre un algoritmo de cifrado mutuo para usar en la comunicación SSL).

Necesito instalar la Java JCE Ilimitada (Java Cryptography Extension Policy). Hay reglas de exportación sobre el uso de esto, por lo que si envía su código al extranjero puede tener implicaciones ... sin embargo, esto es lo que resolvió mi problema.

Este enlace explica cómo instalar las políticas actualizadas http://suhothayan.blogspot.com/2012/05/how-to-install-java-cryptography.html

Este también fue un gran enlace que me ayudó a entender exactamente lo que estaba pasando https://support.f5.com/kb/en-us/solutions/public/15000/200/sol15292.html#id

Esto puede o no ser el problema, pero cuando el apretón de manos falla inmediatamente después del saludo del cliente, parece que el cliente y el servidor no pueden ponerse de acuerdo en algo (en muchos casos son los algoritmos de cifrado los que deben comunicarse mutuamente).


4
2018-01-29 19:48



Está viendo este error muy probablemente porque el almacén de claves al que tenía acceso su JBoss 6 no es accesible para su instancia de JBoss 7.

Lo que recomendaría es lo siguiente.

Su certificado de servidor autofirmado debe ser importado a un almacén de confianza

keytool -import -alias gridserver -file server.crt -storepass $YOUR_PASSWORD_HERE -keystore server.keystore

Agregue las siguientes propiedades a su run.conf

-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=server.keystore
-Djavax.net.debug=ssl # very verbose debug. Turn this off after everything looks good.
-Djavax.net.ssl.keyStorePassword=$YOUR_PASSWORD_HERE
-Djavax.net.ssl.trustStorePassword=$YOUR_PASSWORD_HERE

0
2018-03-22 20:34



El seguimiento de la pila proviene de su código de cliente y su cliente 'Recibió [a] alerta fatal'. En otras palabras, el error de SSL ocurrió en Jboss, no en su cliente.

Por lo tanto, sus TrustManagers personalizados del lado del cliente no tienen nada que ver con eso. Creo que su nuevo Jboss 7 está configurado para requerir un certificado de cliente y su cliente no presentó ninguno.

Para depurar su conexión SSL, use openssl e intente esto:

openssl s_client -connect jboss.server.com:443 

o es un servidor SSLV3

openssl s_client -connect jboss.server.com:443 -ssl3

Esto debería imprimir mucha información interesante.


0
2018-03-23 09:33



Creo que esto está relacionado con un Error de Java 7. Es difícil estar seguro sin más detalles.


0
2018-06-12 02:47



Para mí, la solución fue: System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");


0
2018-01-16 07:35