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

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 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 { @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 

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 

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 
  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

Citando de No más ‘no se puede encontrar una ruta de certificación válida para el objective 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.

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  [  | 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 (Eg 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; 

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 sessionStrategyRegistry = RegistryBuilder.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; } } } 

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 

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 objective 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.

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.

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 repositorys 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 /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 objective 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.

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

   org.apache.httpcomponents httpclient 4.3.6  

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 

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.

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.

Esto resolvió mi problema,

Necesitamos importar el certificado al java local. Si no, podríamos obtener la siguiente excepción.

     javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: construcción de rutas PKIX fallida: sun.security.provider.certpath.SunCertPathBuilderException: no se puede encontrar una ruta de certificación válida para el destino solicitado
         en sun.security.ssl.Alerts.getSSLException (Alerts.java:192)
         en sun.security.ssl.SSLSocketImpl.fatal (SSLSocketImpl.java:1949)
         en sun.security.ssl.Handshaker.fatalSE (Handshaker.java:302)

SSLPOKE es una herramienta donde puede probar la conectividad https desde su máquina local.

Comando para probar la conectividad:

 "%JAVA_HOME%/bin/java" SSLPoke  443 
     sun.security.validator.ValidatorException: construcción de rutas PKIX fallida: 
     sun.security.provider.certpath.SunCertPathBuilderException: no se puede encontrar una ruta de certificación válida para el objective solicitado
         en sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:387)
         en sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:292)
         en sun.security.validator.Validator.validate (Validator.java:260)
         en sun.security.ssl.X509TrustManagerImpl.validate (X509TrustManagerImpl.java:324)
         en sun.security.ssl.X509TrustManagerImpl.checkTrusted (X509TrustManagerImpl.java:229)
         en sun.security.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:124)
         en sun.security.ssl.ClientHandshaker.serverCertificate (ClientHandshaker.java:1496)
         en sun.security.ssl.ClientHandshaker.processMessage (ClientHandshaker.java:216)
         en sun.security.ssl.Handshaker.processLoop (Handshaker.java:1026)
         en sun.security.ssl.Handshaker.process_record (Handshaker.java:961)
         en sun.security.ssl.SSLSocketImpl.readRecord (SSLSocketImpl.java:1062)
         en sun.security.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1375)
         en sun.security.ssl.SSLSocketImpl.writeRecord (SSLSocketImpl.java:747)
         en sun.security.ssl.AppOutputStream.write (AppOutputStream.java:123)
         en sun.security.ssl.AppOutputStream.write (AppOutputStream.java:138)
         en SSLPoke.main (SSLPoke.java:31)
     Causado por: sun.security.provider.certpath.SunCertPathBuilderException: no se puede encontrar una ruta de certificación válida para 
     objective solicitado
         en sun.security.provider.certpath.SunCertPathBuilder.build (SunCertPathBuilder.java:141)
         en sun.security.provider.certpath.SunCertPathBuilder.engineBuild (SunCertPathBuilder.java:126)
         en java.security.cert.CertPathBuilder.build (CertPathBuilder.java:280)
         en sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:382)
         ... 15 más
 keytool -import -alias brinternal -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file  

esto solicitaría primero “Ingresar la contraseña del almacén de claves:” cambiar es la contraseña predeterminada. y finalmente un mensaje “¿Confiar en este certificado? [no]:”, proporcione “sí” para agregar el certificado al almacén de claves.

Verificación:

 C:\tools>"%JAVA_HOME%/bin/java" SSLPoke  443 Successfully connected 

En mi caso, estoy ejecutando MacOs High Sierra con Java 1.6. El archivo cacert está en una ubicación diferente a la mencionada anteriormente en la respuesta de Gabe Martin-Dempesy. El archivo cacert también ya estaba vinculado a otra ubicación (/ Library / Internet Plug-Ins / JavaAppletPlugin.plugin / Contents / Home / lib / security / cacerts).

Usando FireFox, exporté el certificado del sitio web en cuestión a un archivo local llamado “exportCertFile.crt”. A partir de ahí, utilicé keytool para mover el certificado al archivo cacert. Esto solucionó el problema.

 bash-3.2# cd /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/ bash-3.2# keytool -importcert -file ~/exportedCertFile.crt -alias example -keystore cacerts -storepass changeit 

primero Descargue el certificado SSL y luego vaya a la ruta de su compartimento Java ejecute el siguiente comando en la consola.

 C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore 

Cuando tengo este problema, simplemente extraigo el zip de Android Studio en la misma carpeta anterior, eso resolvió mi problema