Yo era conseguir un Handshake de SSL de error de Excepción: PKIX «ruta de acceso no de la cadena» (se describe aquí).
Me fijo por la importación de un certificado de cadena de uso de openssl:

openssl s_client -host www.envmgr.com -port 443 -showcerts > cert_chain.crt

e instalado en mi JDK del almacén de claves:

keytool -import -alias envmgrchain -file cert_chain.crt -keystore cacerts -storepass changeit

Así funciona esto. ¡Hurra. El problema es que estaremos poniendo nuestra aplicación en un servidor en la nube como rackspace o AWS y creo que hay una buena probabilidad de que no vamos a tener acceso a modificar el almacén de claves de la JVM para agregar esta cadena.

Pensé, «no hay problema, sólo voy a añadir esta cadena de certificados al almacén de claves a través de programación», así que me sacó de mi JVM:

keytool -delete -alias envmgrchain -keystore cacerts -storepass changeit

y añade este código:

    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    //Create an empty keystore that we can load certificate into
    trustStore.load(null);
    InputStream fis = new FileInputStream("cert_chain.crt");
    BufferedInputStream bis = new BufferedInputStream(fis);

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    while(bis.available()>0) {
        Collection<? extends Certificate> certs = cf.generateCertificates(bis);
        Iterator<? extends Certificate> iter = certs.iterator();
        //Add each cert in the chain one at a time
        for(int i=0; i<certs.size(); i++) {
            Certificate cert = iter.next();
            String alias = "chaincert"+((i>0)?i:"");
            trustStore.setCertificateEntry(alias, cert);
        }
    }
    bis.close();
    fis.close();
//Add custom keystore to TrustManager
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance("TLSv1");
    ctx.init(null, tmf.getTrustManagers(), null);

Pero cuando lo ejecuto, el PKIX de error vuelve a aparecer. Es el código anterior no equivale a keytool-import? Me siento como la adición de los certificados en el Almacén de claves de forma incorrecta, o no soy de instalar el Almacén de claves en el TrustManager en el camino correcto.

FYI: yo también estoy tratando de solucionar este problema mediante la implementación de un X509TrustManager.

  • Lo que sobre de envío al almacén de confianza que desea utilizar con su aplicación y hacer referencia a ella a través de argumentos de vm?
  • También, aquí es un ejemplo famoso por Andreas Sterbenz llamado InstallCert que hace lo que estamos tratando de hacer, pero usted tendrá que analizar pesar de que el código para obtener lo que desea exactamente: code.google.com/p/java-use-examples/source/browse/trunk/src/com/…
InformationsquelleAutor IcedDante | 2014-06-04

2 Comentarios

  1. 17

    Aquí el código que puede utilizar para los clientes a través de programación añadir su CA en tiempo de ejecución. Usted no necesita poner en cualquier tienda que acaba de llevar todo el PEM archivo codificado. Usted puede incluso difícil de código en su programa por lo que no hay archivo independiente para administrar.

    static String CA_FILE = "ca-cert.pem";
    ...
    
    FileInputStream fis = new FileInputStream(CA_FILE);
    X509Certificate ca = (X509Certificate) CertificateFactory.getInstance("X.509")
                            .generateCertificate(new BufferedInputStream(fis));
    
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null, null);
    ks.setCertificateEntry(Integer.toString(1), ca);
    
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);
    ...

    Tendrá una confianza canal de distribución para asegurarse de que su programa no es modificado mientras se está sentado en el servidor a la espera de ser recogidos o mientras viaja por el cable mientras se está instalando.


    openssl s_client -host http://www.envmgr.com -el puerto 443 -showcerts > cert_chain.crt

    Sólo es necesario confiar en el certificado raíz, y no en toda la cadena. El servidor es responsable por el envío de todos los certificados intermedios necesarios para construir la cadena. Si el servidor no está enviando todos los certificados intermedios necesarios para construir la cadena, entonces el servidor no está configurado.

    El problema que está experimentando es llamado el «Directorio» problema. Es un problema bien conocido en la PKI. Esencialmente, esto significa que un cliente no sabe a dónde ir a buscar a una falta certificado intermedio. Resolver lo que el servidor envíe todos los intermedios, junto con el certificado del servidor. Ver OWASP TLS del Cheatsheet y Regla – Siempre Proveer Todos Los Certificados Necesarios.


    Sólo de la bicicleta de la muda, pero hay todo un tro de la lata de gusanos con Java (especialmente Java 7 y menores):

    SSLContext ctx = SSLContext.getInstance("TLSv1");
    ctx.init(null, tmf.getTrustManagers(), null);

    Puede mejorar, si se desea. Ver SSLSocketFactoryEx en Que los conjuntos de Cifrado para habilitar SSL para Socket?. Se cierra con algunas lagunas en las versiones del protocolo, los conjuntos de cifrado, etc que se ofrecen por defecto en Java SSLSocketFactory.

    • Tanta buena info aquí – gracias! Lo que hago actualmente es la oferta el certificado de mí mismo. He creado una costumbre X509TrustManager que, tras la captura de un CertificateException desde el manager por defecto, los ciclos a través de un montón de certificados en que se guarda en un directorio llamado «trustedCerts». Puedo convertir estos certificados X509 y hacer una comparación de verificación en la cadena de uso de X509Certificate.equals()… si hay una coincidencia, yo acepte el certificado. ¿Crees que el uso de iguales es una comparación válida aquí? (por cierto, si esta pregunta es demasiado grande para un comentario hágamelo saber y voy a empezar una cuestión separada de la misma).
    • «Lo que yo hago actualmente es la oferta el certificado de mí… utilizando una costumbre X509TrustManager …» – sí, su fina para llevar a todo el servidor espera certificado. Eso se llama clavos, y una gran mejora en la seguridad. Sus latidos los mocos de la Web Modelo de Seguridad. Ver OWASP del el Certificado y la Clave Pública de Fijación.
    • Sólo un consejo. Cuando codificar la CA como una Cadena de caracteres en una línea, agregar \n en el lugar de los saltos de línea. No es que yo recomendaría este enfoque. Lo necesitaba para las pruebas a pesar de que
  2. -1

    No. Usted no debe modificar los archivos que vienen con el JRE. Próxima actualización, sus actualizaciones se han ido. Usted debe enviar su propio almacén de confianza, construido a partir de la que viene con el JRE más lo extra certificados de confianza. Esto es parte de la aplicación a construir.

    Si desea modificar su propio almacén de confianza en tiempo de ejecución, vaya por delante, pero entonces usted necesita estar consciente de que la JVM no necesariamente ver los cambios hasta que se reinicia: sin duda no volveré a ver dentro de la misma SSLContext que se utiliza para obtener los certificados que desea agregar.

    • Un montón de buena información aquí. Gracias. ¿Tiene usted una fuente?
    • En una fuente para qué?
    • «Si desea modificar su propio almacén de confianza en tiempo de ejecución, vaya por delante, pero entonces usted necesita estar consciente de que la JVM no necesariamente ver los cambios hasta que se reinicia: sin duda no volveré a ver dentro de la misma SSLContext que se utiliza para obtener los certificados que desea agregar.»
    • Es una consecuencia lógica del hecho de que un Almacén de claves está cargado de un flujo de entrada en lugar de siempre con un Archivo.

Dejar respuesta

Please enter your comment!
Please enter your name here