2012-03-14 10 views
14

外部.pemファイルを.p12ファイルに変換する必要があります。プロセスにユーザー名とパスワードを追加します。 (私はサードパーティの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から実行すると、ユーザーは「ルート」ではないという点が異なります。

したがって、コマンドラインプログラム(openssl)を実行するのではなく、Javaライブラリを使用してpemから.p12に変換する方が良いですか?

それ以外の場合は、サーバー上でいくつかの設定を行う必要があると思います。サーバーのどこにでも.mdファイルが見つかりません。唯一のopenssl.cnfファイルが奇妙なディレクトリにあります(/etc/pki/tls)。新しいopenssl.cnfファイルを別の場所に作成する必要がありますか?

答えて

0

Javaでは、Bouncycastleを使用してください。ただし、学習曲線は急峻であり、ドキュメントが不足しています。ソースディストリビューションの一部として利用可能なサンプルを見ることを強くお勧めします。

PemReaderから始めます。

10

これは、(上記のBouncyCastle PEMReaderを使用して)実行する必要があります。PEMエンコードされた秘密鍵+証明書を取得し、PKCS#12ファイルを出力します。秘密鍵を保護するために使用されたPKCS12に同じパスワードを使用します。 @MugglesMerriweatherの答えに基づいて

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

、V1.51に更新されたバージョン以下の通りです:私が作成するためのすべてを扱うJavaの7クラスを作成した回答に基づいて

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

0

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

} 
関連する問題