Tengo un problema con la conexión SSL autorizada. He creado Struts Action que se conecta al servidor externo con el certificado SSL autorizado por el cliente. En mi Acción, estoy tratando de enviar algunos datos al servidor del banco, pero sin suerte, porque tengo como resultado del servidor el siguiente error:
error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Mi método de mi clase de acción que envía datos al servidor
//Getting external IP from host
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
String IPStr = inIP.readLine(); //IP as a String
Merchant merchant;
System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);
try {
merchant = new Merchant(context.getRealPath("/") + "merchant.properties");
} catch (ConfigurationException e) {
Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
System.err.println("error: " + e.getMessage());
return ERROR;
}
String result = merchant.sendTransData(amount, currency, IPStr, description);
System.out.println("result: " + result);
return SUCCESS;
Mi archivo merchant.properties:
bank.server.url=https://-servernameandport-/
https.cipher=-cipher-
keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0
encoding.source=UTF-8
encoding.native=UTF-8
Por primera vez pensé que esto era un problema de certificado, lo convertí de .pfx a .jks, pero tengo el mismo error, sin cambios.
Respuestas:
La falla del apretón de manos pudo haber ocurrido debido a varias razones:
Como la falla subyacente no se puede identificar, es mejor activar el
-Djavax.net.debug=all
indicador para habilitar la depuración de la conexión SSL establecida. Con la depuración activada, puede determinar qué actividad en el protocolo de enlace ha fallado.Actualizar
Según los detalles ahora disponibles, parece que el problema se debe a una ruta de confianza de certificado incompleta entre el certificado emitido al servidor y una CA raíz. En la mayoría de los casos, esto se debe a que el certificado de la CA raíz está ausente en el almacén de confianza, lo que lleva a la situación en la que no puede existir una ruta de confianza del certificado; el cliente no confía esencialmente en el certificado. Los navegadores pueden presentar una advertencia para que los usuarios puedan ignorar esto, pero no es el mismo caso para los clientes SSL (como la clase HttpsURLConnection , o cualquier biblioteca de Cliente HTTP como Apache HttpComponents Client ).
La mayoría de estas clases / bibliotecas de clientes dependerían del almacén de confianza utilizado por la JVM para la validación del certificado. En la mayoría de los casos, este será el
cacerts
archivo en el directorio JRE_HOME / lib / security. Si la ubicación del almacén de confianza se ha especificado utilizando la propiedad del sistema JVMjavax.net.ssl.trustStore
, entonces el almacén en esa ruta suele ser el utilizado por la biblioteca del cliente. Si tiene dudas, eche un vistazo a suMerchant
clase y descubra la clase / biblioteca que está utilizando para establecer la conexión.Agregar el certificado del servidor que emite CA a este almacén de confianza debería resolver el problema. Puede consultar mi respuesta en una pregunta relacionada sobre cómo obtener herramientas para este propósito, pero la utilidad Java keytool es suficiente para este propósito.
Advertencia : El almacén de confianza es esencialmente la lista de todas las CA en las que confía. Si coloca un certificado que no pertenece a una CA en la que no confía, las conexiones SSL / TLS a los sitios que tienen certificados emitidos por esa entidad se pueden descifrar si la clave privada está disponible.
Actualización n. ° 2: comprensión del resultado de la traza JSSE
El almacén de claves y los almacenes de confianza utilizados por la JVM generalmente se enumeran al principio, algo así como lo siguiente:
Si se usa el almacén de confianza incorrecto, deberá volver a importar el certificado del servidor al correcto o volver a configurar el servidor para usar el que figura en la lista (no se recomienda si tiene varias JVM, y todas se usan para diferentes necesidades).
Si desea verificar si la lista de certificados de confianza contiene los certificados requeridos, entonces hay una sección para el mismo, que comienza como:
Deberá buscar si la CA del servidor es un tema.
El proceso de reconocimiento tendrá algunas entradas destacadas (necesitará conocer SSL para comprenderlas en detalle, pero con el fin de depurar el problema actual, será suficiente saber que generalmente se informa un fallo de reconocimiento de manos en ServerHello.
1. ClientHello
Se informará una serie de entradas cuando se inicie la conexión. El primer mensaje enviado por el cliente en una configuración de conexión SSL / TLS es el mensaje ClientHello, que generalmente se informa en los registros como:
Tenga en cuenta los conjuntos de cifrado utilizados. Esto podría tener que estar de acuerdo con la entrada en su archivo merchant.properties, ya que la biblioteca del banco podría emplear la misma convención. Si la convención utilizada es diferente, no hay motivo de preocupación, ya que ServerHello lo indicará si el conjunto de cifrado es incompatible.
2. ServerHello
El servidor responde con un ServerHello, que indicará si la configuración de la conexión puede continuar. Las entradas en los registros suelen ser del siguiente tipo:
Tenga en cuenta la suite de cifrado que ha elegido; Esta es la mejor suite disponible tanto para el servidor como para el cliente. Por lo general, el conjunto de cifrado no se especifica si hay un error. El certificado del servidor (y opcionalmente toda la cadena) es enviado por el servidor, y se encuentra en las entradas como:
Si la verificación del certificado se realizó correctamente, encontrará una entrada similar a:
Uno de los pasos anteriores no habría tenido éxito, lo que resultaría en la falla de apretón de manos, ya que el apretón de manos generalmente se completa en esta etapa (en realidad no, pero las etapas posteriores del apretón de manos generalmente no causan una falla del apretón de manos). Deberá averiguar qué paso ha fallado y publicar el mensaje apropiado como una actualización de la pregunta (a menos que ya haya entendido el mensaje y sepa qué hacer para resolverlo).
fuente
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
comando para imprimir el contenido. Luego verifique si los certificados en cacerts coinciden con la CA del certificado del banco.changeit
. A menos que haya cambiado.La instalación de Java Cryptography Extension (JCE) Fuerza ilimitada ( para JDK7 | para JDK8 ) podría solucionar este error. Descomprima el archivo y siga el archivo Léame para instalarlo.
fuente
La falla del protocolo de enlace podría ser una implementación de protocolo TLSv1 con errores.
En nuestro caso, esto ayudó con Java 7:
El jvm negociará en este orden. Los servidores con la última actualización harán 1.2, los con errores bajarán a v1 y eso funciona con el v1 similar en java 7.
fuente
Esto también puede suceder cuando el cliente necesita presentar un certificado. Después de que el servidor enumera la cadena de certificados, puede suceder lo siguiente:
3. Solicitud de certificado El servidor emitirá una solicitud de certificado del cliente. La solicitud enumerará todos los certificados que acepta el servidor.
4. Cadena de certificados del cliente Este es el certificado que el cliente envía al servidor.
Si no hay un certificado en la cadena y el servidor lo requiere, obtendrá el error de protocolo de enlace aquí. Una causa probable es que no se encontró la ruta a su certificado.
5. Verificación del certificado El cliente le pide al servidor que verifique el certificado
Este paso solo ocurrirá si está enviando un certificado.
6. Terminado El servidor responderá con una respuesta de verificación
fuente
No creo que esto resuelva el problema al primer interlocutor, pero para los googlers que vienen aquí para obtener respuestas:
En la actualización 51, Java 1.8 prohíbe [1] los cifrados RC4 de forma predeterminada, como podemos ver en la página Notas de la versión:
Si su servidor tiene una fuerte preferencia por este cifrado (o usa solo este cifrado), esto puede desencadenar un
handshake_failure
java.Puede probar la conexión al servidor habilitando los cifrados RC4 (primero, intente sin
enabled
argumentos para ver si desencadena ahandshake_failure
, luego configureenabled
:1 - https://www.java.com/en/download/faq/release_changes.xml
fuente
Tengo este error mientras intentaba usar JDK 1.7. Cuando actualicé mi JDK a jdk1.8.0_66, todo comenzó a funcionar bien.
Entonces, la solución más simple para este problema podría ser: actualice su JDK y podría comenzar a funcionar bien.
fuente
En mi caso, el certificado se importa, el error permanece, esto se solucionó agregando
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
antes de conectarfuente
Suponiendo que está utilizando los protocolos SSL / TLS adecuados, configuró correctamente su
keyStore
ytrustStore
y confirmó que no existen problemas con los certificados en sí, es posible que deba fortalecer sus algoritmos de seguridad .Como se menciona en la respuesta de Vineet , una posible razón por la que recibe este error se debe a que se utilizan conjuntos de cifrado incompatibles. Al actualizar my
local_policy
andUS_export_policy
jars en lasecurity
carpeta de mi JDK con los proporcionados en Java Cryptography Extension (JCE) , pude completar el apretón de manos con éxito.fuente
Hoy encuentro el mismo problema con el cliente OkHttp para OBTENER una URL basada en https. Fue causado por la versión del protocolo Https y la falta de coincidencia del método Cipher entre el lado del servidor y el lado del cliente .
1) verifique la versión del protocolo https de su sitio web y el método de cifrado.openssl>s_client -connect your_website.com:443 -showcerts
Obtendrá mucha información detallada, la información clave se enumera de la siguiente manera:
2) configure su cliente http, por ejemplo, en el caso del cliente OkHttp :Esto conseguirá lo que queremos.
fuente
Encontré un servidor HTTPS que falló de esta manera si mi proceso de cliente Java estaba configurado con
La conexión falló
handshake_failure
después de queServerHello
finalizó correctamente pero antes de que comenzara el flujo de datos.No había un mensaje de error claro que identificara el problema, el error simplemente parecía
Aislé el problema intentando con y sin la
-Djsse.enableSNIExtension=false
opción " "fuente
El mío fue un
TLS
error de versión incompatible.Anteriormente lo
TLSv1
cambié,TLSV1.2
esto resolvió mi problema.fuente
Estoy usando el cliente http com.google.api. Cuando me comunico con un sitio interno de la empresa, tengo este problema cuando utilizo https por error, en lugar de http.
fuente
Tuve un problema similar; la actualización a Apache HTTPClient 4.5.3 lo arregló.
fuente
Ugg! Esto resultó ser simplemente un problema de versión de Java para mí. Obtuve el error de apretón de manos con JRE 1.6 y todo funcionó perfectamente con JRE 1.8.0_144.
fuente
Descargo de responsabilidad: no sé si la respuesta será útil para muchas personas, solo la comparto porque podría serlo.
Recibí este error al usar Parasoft SOATest para enviar solicitudes XML (SOAP).
El problema era que había seleccionado el alias incorrecto del menú desplegable después de agregar el certificado y autenticarlo.
fuente
En mi caso, el sitio web solo puede usar TLSv1.2. y uso apache httpclient 4.5.6, uso este código e instalo jce para resolver esto (JDK1.7):
jce
jdk7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
jdk 8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
código:
fuente
Para solucionar problemas desde la perspectiva del desarrollador (elemento 1) y del administrador del sistema (elementos 2 y 3):
-Djavax.net.debug=ssl:handshake:verbose
.sudo apt install ssldump
o compile desde la fuente siguiendo este enlace si observaUnknown value
en un cifrado cuando ejecuta el siguiente paso.sudo ssldump -k <your-private-key> -i <your-network-interface>
Ejemplo de apretón de manos que no funciona del registro ssldump:
Ejemplo de saludo exitoso del registro ssldump
Ejemplo de registro de Java que no funciona
fuente
En mi caso tuve un problema con la versión 1.1. Estaba reproduciendo el problema fácilmente con curl. El servidor no admitía versiones inferiores a TLS1.2.
Este problema de apretón de manos recibido:
Con la versión 1.2 funcionaba bien:
El servidor estaba ejecutando un Weblogic, y al agregar este argumento en setEnvDomain.sh, funcionó con TLSv1.1:
fuente
Este problema se produce debido a la versión de Java. Estaba usando 1.8.0.231 JDK y obtengo este error. He degradado mi versión de Java de 1.8.0.231 a 1.8.0.171, ahora funciona bien.
fuente