utiliza recomienda propietario migrar kit herramienta generar formato desarrollo crear claves certificados certificado almacén agregar administración java ssl ssl-certificate

java - recomienda - ¿Cómo puede mi biblioteca con certificado ssl incorporado también permitir el uso con certificados predeterminados?



keytool windows (2)

Estoy distribuyendo un contenedor de biblioteca para clientes internos, y la biblioteca incluye un certificado que utiliza para llamar a un servicio que también es interno a nuestra red.

El administrador de confianza se configura de la siguiente manera

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore keystore = KeyStore.getInstance("JKS"); InputStream keystoreStream = clazz.getClassLoader().getResourceAsStream("certs.keystore"); // (on classpath) keystore.load(keystoreStream, "pa55w0rd".toCharArray()); trustManagerFactory.init(keystore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); SSLContext context = SSLContext.getInstance("SSL"); context.init(null, trustManagers, null); SSLSocketFactory socketFact = context.getSocketFactory(); connection.setSSLSocketFactory(socketFact);

Todo esto funciona bien, excepto en los casos en que los usuarios necesitan otros certificados o el certificado predeterminado.

Intenté esto Registrando múltiples almacenes de claves en JVM sin suerte (estoy teniendo problemas para generalizarlo para mi caso)

¿Cómo puedo usar mi certificado y seguir permitiendo que las bibliotecas de usuarios también usen sus propios certificados?


Está configurando una conexión con un almacén de claves personalizado que actúa como un almacén de confianza (un certificado de su servidor en el que confía). No está anulando el comportamiento de JVM predeterminado, por lo que el resto de la conexión que pueden hacer otras aplicaciones que incluyen su biblioteca no se verán afectadas.

Por lo tanto, no necesita un administrador de múltiples almacenes de claves, de hecho, su código funciona perfectamente.

He adjuntado un ejemplo completo a continuación con un almacén de claves google.jks que incluye la CA raíz de Google y una conexión con el almacén de confianza de JVM predeterminado. Esta es la salida

request("https://www.google.com/", "test/google.jks", "pa55w0rd"); //OK request("https://www.aragon.es/", "test/google.jks", "pa55w0rd"); // FAIL sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target request("https://www.aragon.es/", null, null); //OK

El problema no está en el código que ha adjuntado, así que verifique lo siguiente en su código:

  • El almacén de confianza certs.keystore se encuentra realmente en su classpath

  • La configuración del almacén de confianza no se establece a nivel de JVM usando -Djavax.net.ssl.trustStore

  • Los errores encontrados (inclúyalos en su pregunta) están realmente relacionados con la conexión SSL

package test; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyStore; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; public class HTTPSCustomTruststore { public final static void main (String argv[]) throws Exception{ request("https://www.google.com/", "test/google.jks", "pa55w0rd"); //Expected OK request("https://www.aragon.es/","test/google.jks","pa55w0rd"); // Expected FAIL request("https://www.aragon.es/",null,null); //using default truststore. OK } public static void configureCustom(HttpsURLConnection connection, String truststore, String pwd)throws Exception{ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore keystore = KeyStore.getInstance("JKS"); InputStream keystoreStream = HTTPSCustomTruststore.class.getClassLoader().getResourceAsStream(truststore); keystore.load(keystoreStream, pwd.toCharArray()); trustManagerFactory.init(keystore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); SSLContext context = SSLContext.getInstance("SSL"); context.init(null, trustManagers, new java.security.SecureRandom()); SSLSocketFactory socketFact = context.getSocketFactory(); connection.setSSLSocketFactory(socketFact); } public static void request(String urlS, String truststore, String pwd) { try { URL url = new URL(urlS); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); if (truststore != null) { configureCustom((HttpsURLConnection) conn, truststore, pwd); } conn.connect(); int statusCode = conn.getResponseCode(); if (statusCode != 200) { System.out.println(urlS + " FAIL"); } else { System.out.println(urlS + " OK"); } } catch (Exception e) { System.out.println(urlS + " FAIL " + e.getMessage()); } } }


Puede importar los certificados predeterminados en su almacén personalizado para tener un almacén personalizado combinado y usarlo.