webserviceexception unknown_ca sslexception received net handshake_failure fatal error java ssl jboss7.x

sslexception - javax net ssl sslhandshakeexception received fatal alert unknown_ca



Recibiendo SSLHandshakeException: handshake_failure a pesar de que mi cliente ignora todos los certificados (7)

Tengo un programa Java que se conecta a un servidor web mediante 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 está utilizando 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 si esto es un problema de configuración, o si hay un problema con mi código, pero recibo 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 solucionar 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


¿Se resolvió esto alguna vez?

Tuve exactamente el mismo problema, esencialmente estaba recibiendo una excepción de apretón de manos inmediatamente después del cliente. Así que la cadena de eventos fue

  1. Presentaré mi certificado al servidor.
  2. El servidor respondería de inmediato con un fallo en el apretón de manos. (Ni siquiera me devolvería un Server Hello).

Finalmente, descubrí que el servidor requería un algoritmo de cifrado / descifrado más fuerte que el que estaba suministrando en la fase de intercambio inicial (es decir, el Cliente y el Servidor no pudieron acordar un algoritmo de cifrado mutuo para la comunicación ssl).

Necesito instalar el Java JCE ilimitado (Política de extensión de criptografía de Java). Existen reglas de exportación sobre el uso de esto, por lo que si envía su código al extranjero eso 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 fue también un gran enlace que me ayudó a entender exactamente lo que estaba sucediendo en https://support.f5.com/kb/en-us/solutions/public/15000/200/sol15292.html#id

Este puede o no ser el problema, pero cuando el protocolo de enlace 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 encriptación que mutuamente necesitarán comunicarse).


Así que 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 del 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 me funcionó.


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


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

Por lo tanto, los TrustManagers personalizados del lado del cliente no tienen nada que ver con esto. 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 y pruebe 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.


La información que proporciona es muy pequeña, así como el seguimiento de su pila.
Voy a hacer una conjetura aquí.
Lo que sospecho es que en el nuevo servidor el protocolo es TLSv1 mientras sus clientes intentan conectarse con SSLv3 (o menos) y, como resultado, falla el protocolo de enlace.

Cambie sus clientes para usar una versión más alta de TLS o
Haga que su servidor web soporte 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).
Debes habilitar la información de depuración ssl -Djavax.net.debug=ssl


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


Probablemente está viendo este error porque la instancia de JBoss 7 no tiene acceso al almacén de claves al que tuvo acceso su JBoss 6.

Lo que yo recomendaría es lo siguiente.

Su certificado de servidor autofirmado debe importarse en 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