2012-03-14 95 views
14

我得到需要转换为.p12文件的外部文件.pem - 我在过程中添加了用户名和密码。 (我需要这样做是为了利用第三方API)使用或不使用OpenSSL将SSL .pem转换为.p12

使用openssl,该命令是...

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

我可以从终端会话中运行这和它完美的作品。但是,我需要经常这样做,并编写了一个Java类来处理这个问题(我的应用程序主要是使用Tomcat和Apache的.jsp)。当我尝试使用Runtime.exec从Java运行相同的命令时,出现可怕的“无法写入'随机状态'”错误(Using OpenSSL what does "unable to write 'random state'" mean?)。

我假设不同的是,当我从Java运行时,用户不是“root”。

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

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

回答

0

在Java中,使用Bouncycastle,但要警告,学习曲线陡峭且文档稀少。我强烈建议你看看作为源代码发行版的一部分的示例。

从PemReader开始。

10

这应该做你想做的事(使用上面建议的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(); 
} 
0

基于@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(); 
    } 
+0

'SC'代表SpongyCastle提供商。 – EpicPandaForce 2014-10-31 15:57:42

0

基于我创建一个Java 7类,它处理一切为了创造一个答案有效的SSLContext。它也创造了必要的链条。 TODO: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(); 
} 

}