create commands ssl java-7 keystore keytool

ssl - commands - PKIX Path no se encadena con ninguno de los errores de anclas de confianza en Windows Environment



keytool import certificate (4)

Soy un poco idiota de cómo SSL y los servicios web funcionan a un nivel muy detallado. Estoy desarrollando un sistema que llama a varios servicios web, algunos con URL seguras y otros que no tienen problemas. Actualmente, sin embargo, estoy haciendo una integración con la API web LabelServer de Endicia. El servicio web se usa para calcular e imprimir franqueo.

La URL de prueba y WSDL están en: https://www.envmgr.com/LabelService/EwsLabelService.asmx

Utilicé wsimport para crear y configurar un cliente Java para conectarme a este servicio web, pero cuando trato de hacerlo obtengo el error

La validación de ruta de PKIX falló: java.security.cert.CertPathValidatorException: La ruta no encadena con ninguno de los anclajes de confianza

Este error está documentado aquí: Java7 se niega a confiar en el certificado en la tienda de confianza

en el cual se discute cómo Java 7 fuerza un error con certificados autofirmados con clave de acceso "malo". Lo malo en esta situación se define como que no contiene keyCertSign. El servicio web funciona con Java 6. Puedo creer que esta situación podría aplicarse a este certificado, ya que solo se usa como servidor de prueba, pero no sé cómo verificarlo.

Hay un informe de error que está resuelto ( http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7018897 ), pero no estoy seguro de cómo esto se traduce en solucionar el problema de un Windows Tomcat ambiente. Exporté el certificado a mi máquina, pero no estoy seguro de cómo proceder desde allí.

EDITAR: Intenté usar OpenSSL para modificar el certificado y agregarlo a mi almacén de claves como se describe en el enlace "Rehusar a confiar en el certificado en el almacén de confianza" y no funcionó. Parece que este es un proceso que realiza el propietario del certificado, ¿verdad? Me pregunto si hay alguna manera de configurar mi entorno Java 7 para que pase este certificado.


Intente importar el certificado que necesita en java truststore ubicado en jdk_xxx / jre / lib / security / cacerts utilizando keytool

establece el parámetro jvm Djavax.net.debug = ssl para ver más información de depuración


La lógica de validación de la cadena de certificados realmente ha cambiado entre Java 6 y Java 7. Parece que la cadena de certificados se considera inválida porque la fecha de finalización de la validez del certificado intermedio es posterior a la fecha de finalización de la validez del certificado raíz. Este es un error de Java que se corrigió con JDK 1.7.0_72 y 1.8.0_25.

Si no puede actualizar su JDK, aquí hay una solución ya que dice que se encuentra en un entorno de depuración y tiene control sobre su almacén de claves. No puede cambiar ninguno de los certificados de curso (ya que no tiene las claves privadas), pero puede importar el certificado intermedio o de servidor en un almacén de claves local, lo que significa que será de confianza por defecto, y el resto de la cadena valida sin ningún problema.

  1. Descargue el certificado para www.envmgr.com o www.starfieldtech.com como trusted_certificate.pem
  2. Use keytool para importar el certificado en un almacén de claves local llamado my_keystore con keytool -keystore my_keystore -importcert -file trusted_certificate.pem
  3. Inicie wsimport -J-Djavax.net.ssl.trustStore=my_keystore https://www.envmgr.com/LabelService/EwsLabelService.asmx

Las comprobaciones de certificados de Java por defecto son bastante estrictas, y aparentemente se han vuelto más estrictas. Una solución es inicializar un SSLContext con un X509TrustManager personalizado. Un administrador de confianza que no hace nada, es decir, es completamente inseguro, que una vez escribí para las pruebas se ve así:

TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType ) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType ) { } } };

Obviamente, usted querrá verificar la cadena de certificados en un programa real. Podría intentar inicializar un SSLContext con él y llamar a SSLContext.setDefault() si su API no tiene otra forma de configurar SSL. Si la API usa el contexto SSL predeterminado, entonces esto debería funcionar.

El uso de claves no parece ser el problema en este caso, ya que la cadena de certificados no está autofirmada. La prueba de la URL parece mostrar que el certificado de hoja no está autofirmado y (2) los otros dos certificados de la cadena parecen tener habilitada la firma de certificado. Una posibilidad alternativa es que Java 6 y Java 7 tengan tiendas de confianza separadas y que el certificado raíz no se encuentre en la tienda de Java 7. Es posible que desee verificarlo dos veces. Si tiene acceso a OpenSSL, puede obtener la cadena de certificados del servidor con:

openssl s_client -host www.example.com -port 443 -showcerts

Al parecer, la actualización de la tienda de confianza fue la clave (juego de palabras). Los informes de OP:

Descargué OpenSSL para Windows 64 y luego usé este comando para descargar la cadena de certificados:

openssl s_client -host www.webserviceurl.com -port 443 -showcerts > c:/temp/certchain_output.crt

Entonces quiero importarlo en el almacén de claves de mi navegador como tal (desde el directorio de inicio del JDK / jre / lib / security):

keytool -import -alias ca -file certchain_output.crt -keystore cacerts -storepass changeit

Creo que usar X509TrustManager podría proporcionar una solución efectiva también.


Rhashimoto me ayudó a encontrar la solución que funcionó para mí:

Descargué OpenSSL para Windows 64 y luego usé este comando para descargar la cadena de certificados:

openssl s_client -host www.webserviceurl.com -port 443 -showcerts > c:/temp/certchain_output.crt

Entonces quiero importarlo en el almacén de claves de mi navegador como tal (desde el directorio de inicio del JDK / jre / lib / security):

keytool -import -alias ca -file certchain_output.crt -keystore cacerts -storepass changeit

Creo que usar X509TrustManager podría proporcionar una solución efectiva también.