Solucione el error Javax.Net.SSL.SSLHandshakeException
- Protocolos de enlace SSL en Java
-
Solucione la
SSLHandshakeException
debido a la falta del certificado del servidor -
Solucione la excepción
SSLHandShakeException
debido a un certificado de servidor no confiable -
Solucione la excepción
SSLHandShakeException
debido a un certificado incorrecto -
Solucione la excepción
SSLHandShakeException
debido a una versión SSL incompatible y Cipher Suite
Este tutorial demuestra el error javax.net.ssl.SSLHandshakeException
en Java.
Protocolos de enlace SSL en Java
Los protocolos de enlace SSL se utilizan para que el cliente y el servidor establezcan la confianza y la logística necesarias para asegurar la conexión a través de Internet. Hay pasos típicos en las operaciones SSL Handshake que deben seguirse:
- Primero, el cliente proporcionará la lista de todas las suites de cifrado y versiones SSL posibles.
- El servidor aceptará el conjunto de cifrado particular y la versión SSL, que responderá con un certificado.
- Luego, el cliente extraerá la clave pública del certificado dado y responderá con la nueva clave premaestra encriptada.
- Luego, el servidor usará la clave privada para descifrar la clave maestra previa.
- Luego, el cliente y el servidor calcularán el secreto compartido usando la clave maestra previa juntos.
- Finalmente, el cliente y el servidor intercambiarán mensajes que confirman el cifrado y descifrado exitoso del secreto compartido.
Los protocolos de enlace SSL tienen dos tipos. El primero es el SSL unidireccional, que deja que el servidor confíe en todos los clientes, y el segundo es el SSL bidireccional en el que el cliente y el servidor deben aceptar los certificados del otro.
Después de comprender SSL Handshakes, ahora podemos discutir la SSLHandShakeException
en detalle. Hay dos escenarios de SSLHandShakeException
, que se detallan a continuación.
Solucione la SSLHandshakeException
debido a la falta del certificado del servidor
Si una operación SSL Handshake cuando el cliente se está conectando al servidor no recibe ningún certificado, arrojaría la SSLHandShakeException
como se menciona a continuación:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
Received fatal alert: handshake_failure
Para resolver este problema, asegúrese de seguir todos los pasos anteriores. Este problema ocurre cuando el Keystore o las propiedades del sistema no se ingresan correctamente.
Los almacenes de claves son los certificados proporcionados por las autoridades, o también podemos crear nuestros almacenes de claves utilizando la funcionalidad keytool
de JDK. Aquí hay un ejemplo para el almacén de claves:
$ keytool -genkey -keypass password \
-storepass password \
-keystore Server_Keystore.jks
El código keytool
anterior está escrito en el archivo Keystore. Ahora la herramienta de claves
se puede utilizar para extraer un certificado público del archivo Keystore que se generó anteriormente:
$ keytool -export -storepass password \
-file NewServer.cer \
-keystore Server_Keystore.jks
El código anterior exportará el certificado público del almacén de claves como un archivo NewServer.cer
. Ahora, podemos agregarlo al Truststore para el cliente:
$ keytool -import -v -trustcacerts \
-file NewServer.cer \
-keypass password \
-storepass password \
-keystore Client_Truststore.jks
Ahora se generan el almacén de claves para el servidor y el almacén de confianza para el cliente. Podemos pasarlos como propiedades del sistema al servidor con un comando:
-Djavax.net.ssl.keyStore=Client_Keystore.jks -Djavax.net.ssl.keyStorePassword=password
Es necesario para la propiedad del sistema. La ruta del archivo Keystore debe ser absoluta o colocar el archivo Keystore en el mismo directorio desde donde se invoca el comando.
Las rutas relativas no son compatibles. Una vez que siga este proceso, el error de certificado faltante se resolverá y no habrá más SSLHandShakeException
.
Solucione la excepción SSLHandShakeException
debido a un certificado de servidor no confiable
El otro motivo de SSLHandShakeException
es un certificado de servidor que no es de confianza. Cuando un servidor utiliza un certificado autofirmado que no está firmado por las autoridades, arrojará el siguiente error:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Esta excepción se lanzará siempre que el certificado esté firmado por cualquier entidad que no sea el almacén predeterminado. El Truststore predeterminado en JDK envía la información sobre los certificados comunes en uso.
Este problema se puede resolver obligando al cliente a confiar en el certificado presentado por el servidor. Necesitamos usar el Truststore que generamos arriba y pasarlos como propiedades del sistema al cliente:
-Djavax.net.ssl.trustStore=Client_Truststore.jks -Djavax.net.ssl.trustStorePassword=password
Esto resolverá la excepción, pero no es una situación ideal. En una situación ideal, podemos usar el certificado autofirmado, que debe estar certificado por la Autoridad de certificación (CA), luego el cliente puede confiar en ellos por defecto.
Solucione la excepción SSLHandShakeException
debido a un certificado incorrecto
Un apretón de manos también puede fallar debido a un certificado incorrecto. Cuando un certificado no se crea correctamente, arrojará la SSLHandShakeException
:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:
No name matching localhost found
Para verificar si el certificado se creó correctamente, ejecute el siguiente comando:
keytool -v -list -keystore Server_Keystore.jks
El comando anterior mostrará los detalles del propietario del almacén de claves:
...
Owner: CN=localhost, OU=technology, O=delftstack, L=city, ST=state, C=xx
..
El CN del propietario debe coincidir con el CN del servidor y, si no coincide, arrojará la misma excepción que se muestra arriba, ya que se genera debido a los diferentes CN.
Solucione la excepción SSLHandShakeException
debido a una versión SSL incompatible y Cipher Suite
Durante una operación de protocolo de enlace SSL, es posible que haya varios protocolos criptográficos como diferentes versiones de SSL, TLS, etc. Si bien el cliente y el servidor deben ponerse de acuerdo sobre los protocolos criptográficos y las versiones en un protocolo de enlace, el SSL es reemplazado por el TLS para su fuerza criptográfica.
Ahora, por ejemplo, si el servidor está usando el protocolo SSL3 y el cliente está usando el protocolo TLS1.3, ambos no pueden ponerse de acuerdo sobre el protocolo criptográfico y arrojará la SSLHandShakeException
:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Para resolver este problema, debemos verificar que el cliente y el servidor estén utilizando protocolos criptográficos iguales o compatibles.
Del mismo modo, también es necesario disponer de Cipher Suite compatible. Durante un apretón de manos, el cliente proporciona la lista de cifrados y el servidor seleccionará un cifrado para usar.
Si el servidor no puede seleccionar un cifrado adecuado, el código arrojará la siguiente SSLHandShakeException
:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
Received fatal alert: handshake_failure
Normalmente, el cliente y el servidor utilizan una variedad de conjuntos de cifrado; por eso puede ocurrir este error. El error ocurre porque un servidor ha elegido un cifrado muy selectivo.
Para evitar este problema, el servidor utiliza una lista de cifrados selectivos, lo que también es bueno para la seguridad.
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn FacebookArtículo relacionado - Java Error
- Arreglar Java fue iniciado por el código de salida devuelto = 1
- Arreglar JAVA_HOME no se puede determinar a partir del error de registro en R
- Arreglar java.io.IOException: No queda espacio en el dispositivo en Java
- Arreglar Java.IO.NotSerializableException en Java
- Arreglar Java.Lang.IllegalStateException de Android: no se pudo ejecutar el método de la actividad
- Arreglar Java.Lang.NoClassDefFoundError: No se pudo inicializar el error de clase