machine cacerts java ssl https ssl-certificate

java - cacerts - keytool import trusted certificate



Java: sun.security.provider.certpath.SunCertPathBuilderException: no se puede encontrar una ruta de certificación válida para el objetivo solicitado (17)

Tengo una clase que descargará un archivo de un servidor https . Cuando lo ejecuto, devuelve una gran cantidad de errores. Parece que tengo un problema con mi certificado. ¿Es posible ignorar la autenticación cliente-servidor? ¿Si es así, cómo?

package com.da; import java.io.FileOutputStream; import java.io.IOException; import java.nio.CharBuffer; import java.util.concurrent.Future; import org.apache.http.HttpResponse; import org.apache.http.client.utils.URIUtils; import org.apache.http.impl.nio.client.DefaultHttpAsyncClient; import org.apache.http.nio.IOControl; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.client.methods.AsyncCharConsumer; import org.apache.http.nio.client.methods.HttpAsyncGet; import org.apache.http.nio.client.methods.HttpAsyncPost; public class RSDDownloadFile { static FileOutputStream fos; public void DownloadFile(String URI, String Request) throws Exception { java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx", "Lang=EN&AuthToken=package", null); System.out.println("URI Query: " + uri.toString()); HttpAsyncClient httpclient = new DefaultHttpAsyncClient(); httpclient.start(); try { Future<Boolean> future = httpclient.execute( new HttpAsyncGet(uri), new ResponseCallback(), null); Boolean result = future.get(); if (result != null && result.booleanValue()) { System.out.println("/nRequest successfully executed"); } else { System.out.println("Request failed"); } } catch(Exception e){ System.out.println("[DownloadFile] Exception: " + e.getMessage()); } finally { System.out.println("Shutting down"); httpclient.shutdown(); } System.out.println("Done"); } static class ResponseCallback extends AsyncCharConsumer<Boolean> { @Override protected void onResponseReceived(final HttpResponse response) { System.out.println("Response: " + response.getStatusLine()); System.out.println("Header: " + response.toString()); try { //if(response.getStatusLine().getStatusCode()==200) fos = new FileOutputStream( "Response.html" ); }catch(Exception e){ System.out.println("[onResponseReceived] Exception: " + e.getMessage()); } } @Override protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException { try { while (buf.hasRemaining()) { //System.out.print(buf.get()); fos.write(buf.get()); } }catch(Exception e) { System.out.println("[onCharReceived] Exception: " + e.getMessage()); } } @Override protected void onCleanup() { try { if(fos!=null) fos.close(); }catch(Exception e){ System.out.println("[onCleanup] Exception: " + e.getMessage()); } System.out.println("onCleanup()"); } @Override protected Boolean buildResult() { return Boolean.TRUE; } } }

Errores:

URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception SEVERE: I/O error: General SSLEngine problem javax.net.ssl.SSLHandshakeException: General SSLEngine problem at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source) at javax.net.ssl.SSLEngine.wrap(Unknown Source) at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154) at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276) at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79) at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161) at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335) at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275) at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542) at java.lang.Thread.run(Unknown Source) Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source) at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180) ... 9 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(Unknown Source) at sun.security.validator.PKIXValidator.engineValidate(Unknown Source) at sun.security.validator.Validator.validate(Unknown Source) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source) at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source) ... 16 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source) at java.security.cert.CertPathBuilder.build(Unknown Source) ... 21 more onCleanup() [DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem Shutting down Done


  1. Exporte el certificado SSL usando Firefox. Puede exportarlo presionando la URL en el navegador y luego seleccione la opción para exportar el certificado. Supongamos que el nombre del archivo cert es your.ssl.server.name.crt
  2. Vaya a su JRE_HOME/bin o JDK/JRE/bin
  3. Escriba el comando
  4. keytool -keystore ../lib/security/cacerts -import -alias your.ssl.server.name -file ./relative-path-to-cert-file/your.ssl.server.name.crt
  5. Reinicia tu proceso de Java

AVG versión 18.1.3044 (con Windows 10) interfiere con mi aplicación Spring local.

Solución: ingrese en la sección de AVG llamada "Web y correo electrónico" y desactive la "protección de correo electrónico". AVG bloquea el certificado si el sitio no es seguro.


Citando de No más ''no se puede encontrar una ruta de certificación válida para el objetivo solicitado''

cuando intenta abrir una conexión SSL a un host usando JSSE. Lo que esto generalmente significa es que el servidor está utilizando un certificado de prueba (posiblemente generado mediante keytool) en lugar de un certificado de una autoridad de certificación comercial bien conocida como Verisign o GoDaddy. Los navegadores web muestran cuadros de diálogo de advertencia en este caso, pero como JSSE no puede suponer que un usuario interactivo está presente, arroja una excepción por defecto.

La validación de certificados es una parte muy importante de la seguridad de SSL, pero no estoy escribiendo esta entrada para explicar los detalles. Si está interesado, puede comenzar leyendo la propaganda de Wikipedia. Estoy escribiendo esta entrada para mostrar una forma simple de hablar con ese host con el certificado de prueba, si realmente lo desea.

Básicamente, desea agregar el certificado del servidor a KeyStore con sus certificados de confianza

Pruebe el código provisto allí. Podría ayudar.


Compruebe si la ruta de acceso de java está disponible en $PATH .

Si no, ve a la cabeza y actualiza PATH usando PATH=$PATH:/xxx/xxx/jre/bin


El origen de este error en mi instancia de Apache 2.4 (utilizando un certificado comodín de Comodo) era una ruta incompleta al certificado raíz firmado SHA-1. Había múltiples cadenas en el certificado emitido, y la cadena que conducía a un certificado raíz SHA-1 carecía de un certificado intermedio . Los navegadores modernos saben cómo manejar esto, pero Java 7 no lo maneja por defecto (aunque hay algunas formas intrincadas de lograr esto en el código). El resultado son mensajes de error idénticos al caso de los certificados autofirmados:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 22 more

En este caso, se está produciendo el mensaje "no se puede encontrar una ruta de certificación válida para el objetivo solicitado" debido al certificado intermedio faltante. Puede verificar qué certificado falta utilizando la prueba SSL Labs contra el servidor. Una vez que encuentre el certificado apropiado, descárguelo y (si el servidor está bajo su control) agréguelo al paquete de certificados. Alternativamente, puede importar el certificado faltante localmente. Acomodar este problema en el servidor es una solución más general al problema.


El problema aparece cuando su servidor tiene un certificado autofirmado. Para solucionarlo, puede agregar este certificado a la lista de certificados de confianza de su JVM.

En este artículo, el autor describe cómo recuperar el certificado de su navegador y agregarlo al archivo cacerts de su JVM. Puede editar el archivo JAVA_HOME/jre/lib/security/cacerts o ejecutar su aplicación con el parámetro -Djavax.net.ssl.trustStore . Verifique qué JDK / JRE está utilizando también, ya que a menudo es una fuente de confusión.

Consulte también: ¿Cómo se resuelven los nombres de los servidores de certificados SSL? ¿Puedo agregar nombres alternativos con la herramienta de claves? Si se encuentra con java.security.cert.CertificateException: No name matching localhost found excepción java.security.cert.CertificateException: No name matching localhost found .


Esto es lo que funciona de manera confiable para mí en macOS. Asegúrate de reemplazar example.com y 443 con el nombre de host real y el puerto al que intentas conectarte, y dale un alias personalizado. El primer comando descarga el certificado proporcionado del servidor remoto y lo guarda localmente en formato x509. El segundo comando carga el certificado guardado en el almacén de confianza SSL de Java.

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit


Esto también puede deberse al uso de certificados GoDaddy con Java 7 que se firman con SHA2.

Chrome y todos los demás navegadores están comenzando a desaprobar los certificados SSL que se firman usando SHA1, ya que no es tan seguro.

Puede encontrar más información sobre el problema aquí , y cómo resolverlo en su servidor si lo necesita ahora.


La respuesta de @Gabe Martin-Dempesy me fue útil. Y escribí un pequeño guión relacionado con él. El uso es muy simple.

Instale un certificado desde el host:

> sudo ./java-cert-importer.sh example.com

Elimine el certificado que ya se instaló.

> sudo ./java-cert-importer.sh example.com --delete

java-cert-importer.sh

#!/usr/bin/env bash # Exit on error set -e # Ensure script is running as root if [ "$EUID" -ne 0 ] then echo "WARN: Please run as root (sudo)" exit 1 fi # Check required commands command -v openssl >/dev/null 2>&1 || { echo "Required command ''openssl'' not installed. Aborting." >&2; exit 1; } command -v keytool >/dev/null 2>&1 || { echo "Required command ''keytool'' not installed. Aborting." >&2; exit 1; } # Get command line args host=$1; port=${2:-443}; deleteCmd=${3:-${2}} # Check host argument if [ ! ${host} ]; then cat << EOF Please enter required parameter(s) usage: ./java-cert-importer.sh <host> [ <port> | default=443 ] [ -d | --delete ] EOF exit 1 fi; if [ "$JAVA_HOME" ]; then javahome=${JAVA_HOME} elif [[ "$OSTYPE" == "linux-gnu" ]]; then # Linux javahome=$(readlink -f $(which java) | sed "s:bin/java::") elif [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X javahome="$(/usr/libexec/java_home)/jre" fi if [ ! "$javahome" ]; then echo "WARN: Java home cannot be found." exit 1 elif [ ! -d "$javahome" ]; then echo "WARN: Detected Java home does not exists: $javahome" exit 1 fi echo "Detected Java Home: $javahome" # Set cacerts file path cacertspath=${javahome}/lib/security/cacerts cacertsbackup="${cacertspath}.$$.backup" if ( [ "$deleteCmd" == "-d" ] || [ "$deleteCmd" == "--delete" ] ); then sudo keytool -delete -alias ${host} -keystore ${cacertspath} -storepass changeit echo "Certificate is deleted for ${host}" exit 0 fi # Get host info from user #read -p "Enter server host (E.g. example.com) : " host #read -p "Enter server port (Default 443) : " port # create temp file tmpfile="/tmp/${host}.$$.crt" # Create java cacerts backup file cp ${cacertspath} ${cacertsbackup} echo "Java CaCerts Backup: ${cacertsbackup}" # Get certificate from speficied host openssl x509 -in <(openssl s_client -connect ${host}:${port} -prexit 2>/dev/null) -out ${tmpfile} # Import certificate into java cacerts file sudo keytool -importcert -file ${tmpfile} -alias ${host} -keystore ${cacertspath} -storepass changeit # Remove temp certificate file rm ${tmpfile} # Check certificate alias name (same with host) that imported successfully result=$(keytool -list -v -keystore ${cacertspath} -storepass changeit | grep "Alias name: ${host}") # Show results to user if [ "$result" ]; then echo "Success: Certificate is imported to java cacerts for ${host}"; else echo "Error: Something went wrong"; fi;


Para aquellos a los que les gusta Debian y Java preempaquetado:

sudo mkdir /usr/share/ca-certificates/test/ # don''t mess with other certs sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/ sudo dpkg-reconfigure --force ca-certificates # check your cert in curses GUI! sudo update-ca-certificates --fresh --verbose

No olvide verificar /etc/default/cacerts para:

# enable/disable updates of the keystore /etc/ssl/certs/java/cacerts cacerts_updates=yes

Para eliminar cert:

sudo rm /usr/share/ca-certificates/test/test.loc.crt sudo rm /etc/ssl/certs/java/cacerts sudo update-ca-certificates --fresh --verbose


Pude hacerlo funcionar solo con código, es decir, sin necesidad de utilizar la herramienta de claves:

import com.netflix.config.DynamicBooleanProperty; import com.netflix.config.DynamicIntProperty; import com.netflix.config.DynamicPropertyFactory; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.impl.nio.reactor.IOReactorConfig; import org.apache.http.nio.conn.NoopIOSessionStrategy; import org.apache.http.nio.conn.SchemeIOSessionStrategy; import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class Test { private static final DynamicIntProperty MAX_TOTAL_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40); private static final DynamicIntProperty ROUTE_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40); private static final DynamicIntProperty CONNECT_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connect.timeout", 60000); private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.socket.timeout", -1); private static final DynamicIntProperty CONNECTION_REQUEST_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connectionrequest.timeout", 60000); private static final DynamicBooleanProperty STALE_CONNECTION_CHECK = DynamicPropertyFactory.getInstance().getBooleanProperty("X.checkconnection", true); public static void main(String[] args) throws Exception { SSLContext sslcontext = SSLContexts.custom() .useTLS() .loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }) .build(); SSLIOSessionStrategy sslSessionStrategy = new SSLIOSessionStrategy(sslcontext, new AllowAll()); Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create() .register("http", NoopIOSessionStrategy.INSTANCE) .register("https", sslSessionStrategy) .build(); DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.DEFAULT); PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry); connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS.get()); connectionManager.setDefaultMaxPerRoute(ROUTE_CONNECTIONS.get()); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(SOCKET_TIMEOUT.get()) .setConnectTimeout(CONNECT_TIMEOUT.get()) .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT.get()) .setStaleConnectionCheckEnabled(STALE_CONNECTION_CHECK.get()) .build(); CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom() .setSSLStrategy(sslSessionStrategy) .setConnectionManager(connectionManager) .setDefaultRequestConfig(requestConfig) .build(); httpClient.start(); // use httpClient... } private static class AllowAll implements X509HostnameVerifier { @Override public void verify(String s, SSLSocket sslSocket) throws IOException {} @Override public void verify(String s, X509Certificate x509Certificate) throws SSLException {} @Override public void verify(String s, String[] strings, String[] strings2) throws SSLException {} @Override public boolean verify(String s, SSLSession sslSession) { return true; } } }


Si está utilizando el certificado Let''s Encrypt en el servidor de destino y JRE / JDK <8u101 , siga esta respuesta para solucionarlo.


Solo para Windows, siga estos pasos:

  1. En Chrome ve a la configuración.
  2. En Configuración, haga clic en Mostrar configuración avanzada.
  3. En HTTPS / SSL, haga clic en Administrar certificados.
  4. Exportar su certificado.
  5. En las búsquedas de Windows (presionando la tecla de Windows en el teclado), escriba java.
  6. Seleccione la opción (Configurar Java) que abrirá el Panel de control de Java
  7. Seleccione la pestaña Seguridad en el Panel de control de Java
  8. Seleccione Administrar certificados
  9. Haga clic en importar
  10. En la pestaña (Usuario) seleccionada y tipo de certificado como (Certificados de confianza)
  11. Haga clic en el botón importar y busque el certificado descargado e impórtelo.

Tiene dos opciones, importe el certificado autofirmado en el almacén de claves de java para cada JVM en el que se ejecutará el software o pruebe la fábrica SSL no validación:

jdbc:postgresql://myserver.com:5432/mydatabasename?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory


Tuve el mismo problema con el error de certificados y fue debido a SNI, y el cliente http que utilicé no implementó SNI. Entonces, una actualización de la versión hizo el trabajo

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.6</version> </dependency>


Tuve el mismo problema con un certificado de comodín firmado válido de Symantec.

Primero intente ejecutar su aplicación java con -Djavax.net.debug = SSL para ver qué está pasando realmente.

Terminé importando el certificado intermedio que causaba la ruptura de la cadena de certificación .

Descargué el certificado intermedio que falta de symantec (puede ver el enlace de descarga del certificado faltante en el registro de inicio de sesión de ssl: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cer en mi caso).

E importé el certificado en el almacén de claves de Java. Después de importar el certificado intermedio, mi comodín ssl cert finalmente comenzó a funcionar:

keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer


ACTUALIZACIÓN: Que un reinicio ayudó fue una coincidencia (así lo esperaba, ¡hurra!). La verdadera causa del problema era esta: cuando a Gradle se le ordena utilizar un almacén de claves específico, ese almacén de claves también debe contener todos los certificados raíz oficiales. De lo contrario, no puede acceder a las bibliotecas desde los repositorios regulares. Lo que tuve que hacer fue esto:

Importar el certificado autofirmado:

keytool -import -trustcacerts -alias myselfsignedcert -file /Users/me/Desktop/selfsignedcert.crt -keystore ./privateKeystore.jks

Agregue los certificados raíz oficiales:

keytool -importkeystore -srckeystore <java-home>/lib/security/cacerts -destkeystore ./privateKeystore.jks

Quizás el daemon Gradle también se interpuso en el camino. ./gradlew --status pena matar a todos los daemons que se encuentran con ./gradlew --status si las cosas empiezan a parecer sombrías.

PUBLICACIÓN ORIGINAL:

Nadie lo creerá, lo sé. Aún así, si todo lo demás falla, pruébelo: después de reiniciar mi Mac, el problema desapareció. Grrr.

Antecedentes: ./gradlew jar me mantuvo "incapaz de encontrar una ruta de certificación válida para el objetivo solicitado"

Estoy atrapado con un certificado autofirmado, guardado desde el navegador, importado en privateKeystore.jks. Luego se le indicó a Gradle que trabaje con privateKeystore.jks:

org.gradle.jvmargs=-Djavax.net.debug=SSL -Djavax.net.ssl.trustStore="/Users/me/IntelliJ/myproject/privateKeystore.jks" -Djavax.net.ssl.trustStorePassword=changeit

Como se mencionó, esto solo funcionó después de un reinicio.