java - poke - sun.security.validator.validatorexception pkix path building failed
Resolviendo javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Error en la creación de la ruta de PKIX ¿Error? (14)
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Falló la creación de la ruta PKIX: sun.security.provider.certpath.SunCertPathBuilderException: no se encuentra la ruta de certificación válida para el destino solicitado
• Cuando obtuve el error, intenté buscar en Google el significado de la expresión y descubrí que este problema ocurre cuando un servidor cambia su certificado SSL HTTPS y nuestra versión anterior de Java no reconoce la autoridad de certificación raíz (CA) .
• Si puede acceder a la URL HTTPS en su navegador, entonces es posible actualizar Java para reconocer la CA raíz.
• En su navegador, vaya a la URL de HTTPS a la que Java no pudo acceder. Haga clic en la cadena de certificados HTTPS (hay un icono de candado en Internet Explorer), haga clic en el candado para ver el certificado.
• Vaya a “Detalles” del certificado y “Copiar a archivo”. Cópialo en formato Base64 (.cer) . Se guardará en tu escritorio.
• Instale el certificado ignorando todas las alertas.
• Así es como reuní la información del certificado de la URL a la que estaba tratando de acceder.
Ahora tenía que hacer mi versión de java para saber sobre el certificado para que no rechace reconocer la URL. A este respecto, debo mencionar que busqué en Google que la información del certificado raíz permanece por defecto en la ubicación de seguridad / jre / lib / de JDK, y la contraseña predeterminada para acceder es: changeit.
Para ver la información de cacerts los siguientes son los procedimientos a seguir:
• Haga clic en el botón Inicio -> Ejecutar
• Escribe cmd. Se abre el símbolo del sistema (es posible que deba abrirlo como administrador).
• Vaya a su directorio Java/jreX/bin
• Escriba lo siguiente
keytool -list -keystore D: / Java / jdk1.5.0_12 / jre / lib / security / cacerts
Da la lista de los certificados actuales contenidos en el almacén de claves. Se ve algo como esto:
C: / Documents and Settings / NeelanjanaG> keytool -list -keystore D: / Java / jdk1.5.0_12 / jre / lib / security / cacerts
Introduzca la contraseña del almacén de claves: cambiar
Tipo de almacén de claves: jks
Proveedor de almacén de claves: SUN
Su almacén de claves contiene 44 entradas.
verisignclass3g2ca, 26 de marzo de 2004, trustedCertEntry,
Huella digital del certificado (MD5): A2: 33: 9B: 4C: 74: 78: 73: D4: 6C: E7: C1: F3: 8D: CB: 5C: E9
entrustclientca, 9 de enero de 2003, trustedCertEntry,
Huella digital del certificado (MD5): 0C: 41: 2F: 13: 5B: A0: 54: F5: 96: 66: 2D: 7E: CD: 0E: 03: F4
thawtepersonalbasicca, 13 de febrero de 1999, trustedCertEntry,
Huella digital del certificado (MD5): E6: 0B: D2: C9: CA: 2D: 88: DB: 1A: 71: 0E: 4B: 78: EB: 02: 41
addtrustclass1ca, 1 de mayo de 2006, trustedCertEntry,
Huella digital del certificado (MD5): 1E: 42: 95: 02: 33: 92: 6B: B9: 5F: C0: 7F: DA: D6: B2: 4B: FC
verisignclass2g3ca, 26 de marzo de 2004, trustedCertEntry,
Huella digital del certificado (MD5): F8: BE: C4: 63: 22: C9: A8: 46: 74: 8B: B8: 1D: 1E: 4A: 2B: F6
• Ahora tenía que incluir el certificado previamente instalado en los cacerts.
• Para esto el siguiente es el procedimiento:
keytool –import –noprompt –trustcacerts –alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD
Si está utilizando Java 7:
keytool –importcert –trustcacerts –alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit
• Luego agregará la información del certificado al archivo cacert.
¡Es la solución que encontré para la excepción mencionada anteriormente!
Edición: - Intenté formatear la pregunta y acepté la respuesta de forma más presentable en el mío Blog
Aquí está el tema original:
Estoy recibiendo este error
mensaje detallado sun.security.validator.ValidatorException: Falló la construcción de la ruta PKIX:
sun.security.provider.certpath.SunCertPathBuilderException: no se puede encontrar una ruta de certificación válida para el destino solicitadocause javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Falló la creación de la ruta PKIX: sun.security.provider.certpath.SunCertPathBuilderException: no se encuentra la ruta de certificación válida para el destino solicitado
Estoy usando Tomcat 6 como servidor web. Tengo dos https webbapplication instalados en tomcat diferente en un puerto diferente pero en la misma máquina. Diga App1(port 8443)
y App2(port 443)
. App1
conecta a App2
. Cuando App1
conecta a App2 i
error anterior. Sé que este es un error muy común, así que encontré muchas soluciones en diferentes foros y sitios. Tengo debajo la entrada en server.xml
de server.xml
es decir
keystoreFile="c:/.keystore"
keystorePass="changeit"
Cada sitio dice la misma razón por la que el certificado otorgado por app2 no se encuentra en el almacén confiable de app1 jvm. Esto parece ser cierto también cuando estoy cansado de acceder a la misma URL en el navegador IE, funciona (con el calentamiento, hay un problema con el certificado de seguridad de este sitio web. Aquí digo, continúe con este sitio web), pero cuando la misma url es afectada por cliente java (en mi caso). Así que me sale el error anterior. Así que para ponerlo en Trustore probé estas opciones de árbol, es decir
Opción 1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Opción2 Configuración abajo en la variable de entorno
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:/.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Opción 3 Configuración abajo en la variable de entorno
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:/.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Pero nada funcionó .
Lo que finalmente funcionó es ejecutar el enfoque java sugerido en ¿Cómo manejar certificados SSL no válidos con Apache HttpClient? por Pascal Thivent es decir ejecutando el programa InstallCert.
Pero este enfoque está bien para la configuración de devbox, pero no puedo usarlo en el entorno de producción.
Me pregunto por qué los tres enfoques mencionados anteriormente no funcionaron cuando he mencionado los mismos valores en server.xml
del servidor app2
y los mismos valores en el almacén de confianza al configurar
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
en el programa app1
.
Para más información así es como estoy haciendo la conexión.
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
if (conn instanceof HttpsURLConnection) {
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
conn1.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
reply.load(conn1.getInputStream());
Cómo trabajar en Tomcat 7
Quería admitir un certificado autofirmado en una aplicación Tomcat, pero el siguiente fragmento no funcionó
import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HTTPSPlayground {
public static void main(String[] args) throws Exception {
URL url = new URL("https:// ... .com");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
httpURLConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
String serializedMessage = "{}";
wr.writeBytes(serializedMessage);
wr.flush();
wr.close();
int responseCode = httpURLConnection.getResponseCode();
System.out.println(responseCode);
}
}
esto es lo que resolvió mi problema:
1) Descargar el archivo .crt
echo -n | openssl s_client -connect <your domain>:443 | sed -ne ''/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'' > ~/<your domain>.crt
- Reemplace
<your domain>
con su dominio (por ejemplo,jossef.com
)
2) Aplicar el archivo .crt
en el cacerts
certificados de cacerts
de Java
keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <JAVA HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
- Reemplace
<your domain>
con su dominio (por ejemplo,jossef.com
) - Reemplace
<JAVA HOME>
con su directorio de inicio de Java
3) hackearlo
Aunque he instalado mi certificado en los almacenes de certificados predeterminados de Java
, Tomcat lo ignora (parece que no está configurado para usar los almacenes de certificados predeterminados de Java).
Para hackear esto, agrega lo siguiente en tu código:
String certificatesTrustStorePath = "<JAVA HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
// ...
El siguiente código funciona para mí:
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
HttpsURLConnection conn = null;
URL url = new URL(serviceUrl);
conn = (HttpsURLConnection) url.openConnection();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
En mi caso, el problema era que el servidor web solo enviaba el certificado y la CA intermedia, no la CA raíz. Al agregar esta opción JVM se resolvió el problema: -Dcom.sun.security.enableAIAcaIssuers=true
El soporte para el método de acceso de caIssuers de la extensión de Acceso a la Información de la Autoridad está disponible. Está deshabilitado de forma predeterminada por compatibilidad y se puede habilitar estableciendo la propiedad del sistema
com.sun.security.enableAIAcaIssuers
en el valor verdadero.Si se establece en verdadero, la implementación PKPIX de CertPathBuilder de Sun usa la información en la extensión AIA de un certificado (además de las CertStores que se especifican) para encontrar el certificado de CA emisora, siempre que sea un URI de tipo ldap, http o ftp.
Es una falla de Java que no utiliza el almacén de claves estándar del sistema operativo como MacOS X. Presenté una solicitud de cambio hoy, visite http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8185892
Escribí un pequeño script win32 (WinXP 32bit testet) CMD estúpido (línea de comandos) que busca todas las versiones de Java en los archivos de programa y les agrega un certificado. La contraseña debe ser la "changeit" predeterminada o cambiarla usted mismo en el script :-)
@echo off
for /F %%d in (''dir /B %ProgramFiles%/java'') do (
%ProgramFiles%/Java/%%d/bin/keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%/Java/%%d/lib/security/cacerts -storepass changeit
)
pause
Estaba usando jdk1.8.0_171
cuando enfrenté el mismo problema. Intenté las 2 soluciones principales aquí (agregando un certificado usando keytool y otra solución que tiene un truco) pero no funcionaron para mí.
1.8.0_181
mi JDK a 1.8.0_181
y 1.8.0_181
a la 1.8.0_181
.
Mi archivo de cacerts estaba totalmente vacío. Resolví esto copiando el archivo cacerts de mi máquina con Windows (que está usando Oracle Java 7) y lo escupí a mi caja de Linux (OpenJDK).
cd %JAVA_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp
y luego en la máquina linux
cp /tmp/cacerts /etc/ssl/certs/java/cacerts
Ha funcionado muy bien hasta ahora.
Otra razón podría ser una versión obsoleta de JDK. Estaba usando la versión 1.8.0_60 de jdk, simplemente actualizándome a la última versión solucioné el problema del certificado.
Para Tomcat ejecutándose en el servidor Ubuntu, para saber qué Java se está utilizando, use el comando "ps -ef | grep tomcat":
Muestra:
/home/mcp01$ **ps -ef |grep tomcat**
tomcat7 28477 1 0 10:59 ? 00:00:18 **/usr/local/java/jdk1.7.0_15/bin/java** -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
1005 28567 28131 0 11:34 pts/1 00:00:00 grep --color=auto tomcat
Entonces, podemos ir a: cd /usr/local/java/jdk1.7.0_15/jre/lib/security
El archivo de cacerts predeterminado se encuentra aquí. Inserte el certificado no confiable en él.
Para mí, este error también apareció al intentar conectarse a un proceso detrás de un proxy inverso NGINX que estaba manejando el SSL.
Resultó que el problema era un certificado sin concatenar toda la cadena de certificados. Cuando agregué certificados intermedios, el problema fue resuelto.
Espero que esto ayude.
Tengo este problema también.
Intenté casi todo agregando el certificado SSL a .keystore, pero no funcionaba con Java1_6_x. Para mí, fue útil si comenzamos a utilizar una versión más nueva de Java, Java1_8_x como JVM.
Usando Tomcat 7 bajo Linux, esto hizo el truco.
String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Bajo Linux, $JAVA_HOME
no siempre se configura, pero generalmente /etc/alternatives/jre
apunta a $JAVA_HOME/jre
Debe agregar el certificado para App2 al archivo de almacén de confianza de la JVM usada ubicado en %JAVA_HOME%/lib/security/cacerts
.
Primero, puede verificar si su certificado ya está en el almacén de confianza ejecutando el siguiente comando: keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"
(no necesita proporcionar una contraseña)
Si falta su certificado, puede obtenerlo descargándolo con su navegador y agregarlo al almacén de confianza con el siguiente comando:
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
Después de importar, puede ejecutar el primer comando nuevamente para verificar si su certificado fue agregado.
La información de Sun / Oracle se puede encontrar here .