Seguí este problema a un proveedor de certificados que no es parte de los hosts de confianza JVM predeterminados a partir de JDK 8u74
. El proveedor es www.identrust.com , pero ese no era el dominio al que intentaba conectarme. Ese dominio había obtenido su certificado de este proveedor. Consulte ¿La cobertura de raíz cruzada confiará en la lista predeterminada en JDK / JRE? - Lea un par de entradas. Consulte también Qué navegadores y sistemas operativos admiten Let's Encrypt .
Entonces, para conectarme al dominio que me interesaba, que tenía un certificado emitido identrust.com
, hice los siguientes pasos. Básicamente, tenía que obtener el DST Root CA X3
certificado identrust.com ( ) para que JVM confiara en él. Pude hacerlo usando Apache HttpComponents 4.5 así:
1: Obtenga el certificado de confianza en las Instrucciones de descarga de la cadena de certificados . Haga clic en el enlace DST Root CA X3 .
2: Guarde la cadena en un archivo llamado "DST Root CA X3.pem". Asegúrese de agregar las líneas "----- BEGIN CERTIFICATE -----" y "----- END CERTIFICATE -----" en el archivo al principio y al final.
3: Cree un archivo de almacén de claves de Java, cacerts.jks con el siguiente comando:
keytool -import -v -trustcacerts -alias IdenTrust -keypass yourpassword -file dst_root_ca_x3.pem -keystore cacerts.jks -storepass yourpassword
4: Copie el almacén de claves cacerts.jks resultante en el directorio de recursos de su aplicación java / (maven).
5: Use el siguiente código para cargar este archivo y adjuntarlo al Apache 4.5 HttpClient. Esto resolverá el problema para todos los dominios que tienen certificados emitidos por indetrust.com
util oracle que incluye el certificado en el almacén de claves predeterminado de JRE.
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File(CalRestClient.class.getResource("/cacerts.jks").getFile()), "yourpasword".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
Cuando el proyecto se construye, los cacerts.jks se copiarán en el classpath y se cargarán desde allí. En este momento, no probé con otros sitios ssl, pero si el código anterior "encadena" en este certificado, también funcionarán, pero de nuevo, no lo sé.
Referencia: contexto SSL personalizado y ¿Cómo acepto un certificado autofirmado con una conexión HttpsURLConnection de Java?