wake-up-neo.com

Konvertieren Sie SSL .pem mit oder ohne OpenSSL in .p12

Ich erhalte externe .pem-Dateien, die in .p12-Dateien konvertiert werden müssen. Ich füge dabei einen Benutzernamen und ein Kennwort hinzu. (Ich muss dies tun, um eine API eines Drittanbieters zu verwenden.) 

Mit openssl lautet der Befehl ...

openssl pkcs12 -export -in xxxx.pem -inkey xxxx.pem -out xxx.p12 -passout pas:newpassword -name "newname"

Ich kann dies von einer Terminalsitzung aus ausführen und es funktioniert perfekt. 

Ich muss dies jedoch häufig tun und habe eine Java-Klasse geschrieben, die dieses und mehr behandelt (meine Anwendung ist meistens .jsp mit Tomcat und Apache). Wenn ich versuche, den gleichen Befehl von Java mit Runtime.exec auszuführen, erhalte ich den gefürchteten Fehler "Unglücklicher Zustand kann nicht geschrieben werden" ( Bei Verwendung von OpenSSL bedeutet "Unglücklicher Zustand nicht schreiben" "? ). 

Ich gehe davon aus, dass der Unterschied beim Ausführen von Java nicht "root" ist. 

Gibt es also einen besseren Weg, von Pem in .p12 mithilfe einer Java-Bibliothek zu konvertieren, als ein Befehlszeilenprogramm (d. H. Openssl) auszuführen? 

Andernfalls muss ich auf meinem Server einige Einstellungen vornehmen. Ich kann keine .md-Datei irgendwo auf dem Server finden. Die einzige openssl.cnf-Datei befindet sich in einem seltsamen Verzeichnis (/etc/pki/tls). Muss ich woanders eine neue openssl.cnf-Datei erstellen? 

15
DrDave

Dies sollte das tun, was Sie tun möchten (mit dem oben beschriebenen BouncyCastle PEMReader). Nehmen Sie einen PEM-codierten privaten Schlüssel + Zertifikat und geben Sie eine PKCS # 12-Datei aus. Verwendet das gleiche Kennwort für das PKCS12, das zum Schutz des privaten Schlüssels verwendet wurde.

public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password) throws Exception {
    // Get the private key
    FileReader reader = new FileReader(keyFile);

    PEMReader pem = new PEMReader(reader, new PasswordFinder() {
        @Override public char[] getPassword() {
            return password.toCharArray();
        }
    });

    PrivateKey key = ((KeyPair)pem.readObject()).getPrivate();

    pem.close();
    reader.close();

    // Get the certificate      
    reader = new FileReader(cerFile);
    pem = new PEMReader(reader);

    X509Certificate cert = (X509Certificate)pem.readObject();

    pem.close();
    reader.close();

    // Put them into a PKCS12 keystore and write it to a byte[]
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(null);
    ks.setKeyEntry("alias", (Key)key, password.toCharArray(), new Java.security.cert.Certificate[]{cert});
    ks.store(bos, password.toCharArray());
    bos.close();
    return bos.toByteArray();
}
13

Verwenden Sie in Java Bouncycastle , aber seien Sie gewarnt: Die Lernkurve ist steil und die Dokumentation knapp. Ich empfehle Ihnen dringend, sich die Beispiele anzusehen, die in der Quelldistribution enthalten sind

Beginnen Sie mit dem PemReader.

1
Bruno Grieder

Basierend auf der Antwort von @MugglesMerriweather ist eine aktualisierte Version von v1.51 die folgende:

public static byte[] convertPEMToPKCS12(final String keyFile, final String cerFile,
        final String password)
        throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException
    {
        // Get the private key
        FileReader reader = new FileReader(keyFile);

        PEMParser pem = new PEMParser(reader);
        PEMKeyPair pemKeyPair = ((PEMKeyPair)pem.readObject());
        JcaPEMKeyConverter jcaPEMKeyConverter = new JcaPEMKeyConverter().setProvider("SC");
        KeyPair keyPair = jcaPEMKeyConverter.getKeyPair(pemKeyPair);

        PrivateKey key = keyPair.getPrivate();

        pem.close();
        reader.close();

        // Get the certificate
        reader = new FileReader(cerFile);
        pem = new PEMParser(reader);

        X509CertificateHolder certHolder = (X509CertificateHolder) pem.readObject();
        Java.security.cert.Certificate X509Certificate =
            new JcaX509CertificateConverter().setProvider("SC")
                .getCertificate(certHolder);

        pem.close();
        reader.close();

        // Put them into a PKCS12 keystore and write it to a byte[]
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(null);
        ks.setKeyEntry("alias", (Key) key, password.toCharArray(),
            new Java.security.cert.Certificate[]{X509Certificate});
        ks.store(bos, password.toCharArray());
        bos.close();
        return bos.toByteArray();
    }
1
EpicPandaForce

Basierend auf den Antworten habe ich eine Java 7-Klasse erstellt, die alles für die Erstellung eines gültigen SSLContextes übernimmt. Es schafft auch die notwendige Kette. TODO: ggf. Trustmanager.

public final class SSL_Context {
    private static SSL_Context instance = new SSL_Context();

public static SSL_Context getInstance() {
    return instance;
}

private SSLContext sslContext = null;
private SSL_Context() {
    try {
        sslContext = generateSSLContext();
    }
    catch (Exception e)
    {
        ErrorLogger.logException(e);
    }
}

final private void dumpKeyStore(KeyStore keyStore)
{
    try {
        // List the aliases
        Enumeration aliases = keyStore.aliases();
        for (; aliases.hasMoreElements(); ) {
            String alias = (String) aliases.nextElement();

            // Does alias refer to a private key?
            boolean a = keyStore.isKeyEntry(alias);

            // Does alias refer to a trusted certificate?
            boolean b = keyStore.isCertificateEntry(alias);
            ErrorLogger.log(alias + " " + a + " " + b, 2);
        }
    } catch (Exception e) {
        ErrorLogger.logException(e);
    }
}


final private KeyStore convertPEMToPKCS12(final String keyAndPubFile, final String chainFile, final String password) {
    try {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        PrivateKey key;
        Certificate pubCert;

        try (FileReader reader = new FileReader(keyAndPubFile);
             PEMParser pem = new PEMParser(reader)) {
            PEMKeyPair pemKeyPair = ((PEMKeyPair) pem.readObject());
            JcaPEMKeyConverter jcaPEMKeyConverter = new JcaPEMKeyConverter().setProvider("BC");
            KeyPair keyPair = jcaPEMKeyConverter.getKeyPair(pemKeyPair);
            key = keyPair.getPrivate();


            X509CertificateHolder certHolder = (X509CertificateHolder) pem.readObject();
            pubCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
        }

        // Get the certificates
        try (FileReader reader = new FileReader(chainFile);
             PEMParser pem = new PEMParser(reader)) {

            //load all certs
            LinkedList<Certificate> certsll = new LinkedList<>();
            X509CertificateHolder certHolder = (X509CertificateHolder) pem.readObject();
            do {
                Certificate X509Certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
                certsll.add(X509Certificate);
            }
            while ((certHolder = (X509CertificateHolder) pem.readObject()) != null);

            Certificate[] chain = new Certificate[certsll.size()+1];
            chain[0] = pubCert;

            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(null);

            int i = 1;
            for (Certificate cert : certsll) {
                ks.setCertificateEntry("chain" + i, cert);
                chain[i] = ks.getCertificate("chain" + i);
                i++;
            }

            ks.setKeyEntry("cert", key, password.toCharArray(), chain);

            return ks;
        }
    }
    catch (Exception e)
    {
        ErrorLogger.logException(e);
    }
    return null;
}

final private SSLContext generateSSLContext()
{
    String keyStorePassword = "";
    try {
        KeyStore keyStore = convertPEMToPKCS12("ssl/keyandcert.pem", "ssl/ca_bundle.crt", keyStorePassword);
        SSLContext sslContext = SSLContext.getInstance("TLSv1");
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
        sslContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
        return sslContext;

    } catch (Exception e) {
        ErrorLogger.logException(e);
    }
    return null;
}

final public SSLContext getContext() {
    return sslContext;
}

final public static void main(String args[])
{
        getInstance().getContext();
}

}
0
sascha.arthur