转换 SSL .pem 为 .p12,无论有没有 OpenSSL

2022-09-02 04:20:18

我得到需要转换为文件的外部文件 - 我在此过程中添加了用户名和密码。(我需要这样做才能利用第三方API。.pem.p12

使用 ,该命令是...openssl

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

我可以从终端会话运行它,它可以完美地工作。

但是,我需要经常这样做,并编写了一个Java类来处理这个问题以及更多(我的应用程序主要使用Tomcat和Apache)。当我尝试使用 Java 运行相同的命令时,我得到可怕的“无法写入'随机状态'”错误(使用 OpenSSL“无法写入'随机状态'”是什么意思?.jspRuntime.exec

我假设区别在于,当我从Java运行时,用户不是“root”。

那么,有没有更好的方法使用Java库从pem转换为.p12,而不是执行命令行程序(即openssl)?

否则,我想我需要在服务器上进行一些配置。我在服务器上的任何地方都找不到任何文件。唯一的文件位于一个奇怪的目录()。我是否需要在其他地方创建新文件?.mdopenssl.cnf/etc/pki/tlsopenssl.cnf


答案 1

这应该做你想做的事情(按照上面的建议使用BouncyCastle PEMReader) - 获取PEM编码的私钥+证书,并输出PKCS#12文件。对用于保护私钥的 PKCS12 使用相同的密码。

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();
}

答案 2

根据@MugglesMerriweather的答案,v1.51的更新版本如下:

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();
    }

推荐