Saltar al contenido

Certificados Java y SSL

Solución:

Descubrí que para garantizar la máxima seguridad / validez, tengo que importar el certificado SSL que utiliza mi sitio web en mi aplicación.

Tiene parcialmente razón cuando hace esa declaración. No es necesario importar su certificado SSL. Es suficiente que se importe el certificado de CA de StartSSL.

Además, no existe la importación de un certificado en una aplicación Java. El soporte SSL en Java se basa en el concepto de almacenes de claves y almacenes de confianza, y no en algún certificado empaquetado dentro de su aplicación. Si está publicando su aplicación para que la descarguen y ejecuten los usuarios finales, no es necesario que publique su certificado o, para el caso, su clave privada en su aplicación. La clave privada y el certificado asociado se almacenarían en un almacén de claves, al que solo usted puede acceder.

Los usuarios finales de su aplicación dependerían del soporte SSL dentro del tiempo de ejecución de Java, que permitiría a la aplicación establecer conexiones SSL a los sitios, después de que se verifique el certificado del servidor. El tiempo de ejecución de Java se envía con un conjunto predeterminado de certificados CA en un almacén de confianza, y el único requisito previo para que las conexiones SSL se establezcan con éxito es que el certificado SSL del servidor sea emitido por una de las CA en el almacén de confianza. Los certificados de StartSSL no están presentes en el almacén de confianza del tiempo de ejecución de Java, al menos a partir de la versión 6, y por lo tanto:

  • Puede indicar a sus usuarios finales que realicen la actividad de importar el certificado de CA StartSSL en el almacén de confianza de Java. Los enlaces que pueden ayudar incluyen este hilo del foro StartSSL (solo se necesitan los primeros 4 pasos para importar los certificados de CA a un almacén de confianza), un proyecto de GitHub y esta publicación de blog; un descargo de responsabilidad: no he intentado usar ninguno de esos y debe usarlo bajo su propio riesgo.
  • O bien, puede inicializar su aplicación con su propio almacén de confianza utilizando el -Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password> Indicadores de inicio de JVM, o ejecute el siguiente código antes de inicializar las conexiones SSL:

    System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>");
    System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>");
    

    Este es un enfoque viable solo si su aplicación es una aplicación Java SE que no es un subprograma (o una aplicación con restricciones similares sobre cómo se especifica el almacén de confianza).


También sería útil leer la documentación de la herramienta de claves de Java.

El siguiente método carga el almacén de claves predeterminado (cacerts), comprueba si hay un certificado instalado y, en caso contrario, lo instala. Elimina la necesidad de ejecutar manualmente el keystore comando en cualquier servidor.

Se asume que la contraseña predeterminada del almacén de claves (changeit) no se modifica, actualice CACERTS_PASSWORD que no. Tenga en cuenta que el método guarda el almacén de claves después de agregar un certificado, por lo que después de ejecutarse una vez, el certificado estará permanentemente en el almacén.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

/**
 * Add a certificate to the cacerts keystore if it's not already included
 */
public class SslUtil {
    private static final String CACERTS_PATH = "/lib/security/cacerts";

    // NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG
    // DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE
    // ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO!
    private static final String CACERTS_PASSWORD = "changeit";

    /**
     * Add a certificate to the cacerts keystore if it's not already included
     * 
     * @param alias The alias for the certificate, if added
     * @param certInputStream The certificate input stream
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream)
            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
        //get default cacerts file
        final File cacertsFile = new File(System.getProperty("java.home") + CACERTS_PATH);
        if (!cacertsFile.exists()) {
            throw new FileNotFoundException(cacertsFile.getAbsolutePath());
        }

        //load cacerts keystore
        FileInputStream cacertsIs = new FileInputStream(cacertsFile);
        final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
        cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray());
        cacertsIs.close();

        //load certificate from input stream
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        final Certificate cert = cf.generateCertificate(certInputStream);
        certInputStream.close();

        //check if cacerts contains the certificate
        if (cacerts.getCertificateAlias(cert) == null) {
            //cacerts doesn't contain the certificate, add it
            cacerts.setCertificateEntry(alias, cert);
            //write the updated cacerts keystore
            FileOutputStream cacertsOs = new FileOutputStream(cacertsFile);
            cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray());
            cacertsOs.close();
        }
    }
}

Úselo así:

SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt"));

Aparentemente, los ingenieros de mailgun, por alguna razón, no quieren darnos instrucciones claras sobre cómo resolver esto. Esto es lo que hice

Ejecutamos tomcat8 y nos conectamos a través de los servicios web de jersey a la API de mailgun. Seguí las instrucciones de este usuario y funcionó bien. Espero que esto ayude a alguien.

El 22 de enero, actualizamos nuestros certificados SSL debido a que la infraestructura de PKI de Symantec ya no es de confianza. Algunas versiones anteriores de Java no tienen la CA “DigiCert Global Root G2”.

Hay varias opciones:

Importe la CA “DigiCert Global Root G2” a su archivo “cacerts”. Actualice su JRE a 8u91 (o superior), que incluye esta raíz. Para importar “DigiCert Global Root G2” Puede descargar la raíz desde https://www.digicert.com/digicert-root-certificates.htm. Asegúrese de descargar el certificado raíz correcto.

Una vez que se descargue el certificado, deberá importarlo con un comando como el siguiente:

keytool -import -trustcacerts -keystore / path / to / cacerts -storepass changeit -noprompt -alias digicert-global-root-g2 -file /path/to/digicert.crt Deberá establecer la ruta a su almacén de claves Java y el ubicación del certificado raíz que descargó.


Entonces 1. /path/to/digicert.crt es el archivo que acaba de descargar. 2. / ruta / a / cacerts: se encuentra en su ruta JRE. “Find / -name cacerts -print” esto le ayudará a encontrar rápidamente todos los cacerts de Java en su sistema de archivos. Para mí fue / usr / lib / jvm / java-7-openjdk-amd64 / jre / lib / security / cacerts

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *