2010-06-22 109 views
3

我有一个.PEM file,我要转换为一个PKCS12文件(PFX),我知道我可以使用下面的命令openssl轻松地完成这一点:转换为.pem证书.PFX编程使用OpenSSL

Create a PKCS#12 file: 

openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate" 

这是伟大的,但我想这样做编程方式使用OpenSSL电话。不幸的是,OpenSSL的文档并不理想。

我看着这样使用其他库:

使用.NET:我可以从一个PEM文件X509Certificate2对象,但这只是抓住了第一个证书,而忽略任何中间CA的PEM文件。

使用Mentalis.org安全库:我可以从一个PEM文件证书的对象,但我看到的文档中的以下内容:

备注 此实现只读取PEM文件 证书。 不从 证书文件中读取私钥(如果存在)。

所以,这并没有帮助我。我也需要那个私钥。

我基本上需要重新创建PSS> PFX的OpenSSL命令行工具操作,但在代码中。

有没有更简单的方法来做到这一点?

回答

4

你可以使用BouncyCastle(假设C#,因为你提到.NET)。

比方说localhost.pem这里包含证书和私钥,这样的事情应该工作:

using System; 
using System.Collections; 
using System.Linq; 
using System.Text; 
using System.IO; 

using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.OpenSsl; 
using Org.BouncyCastle.Pkcs; 
using Org.BouncyCastle.X509; 
using Org.BouncyCastle.Security; 

namespace TestApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      StreamReader sr = File.OpenText("localhost.pem"); 
      IPasswordFinder passwordFinder = new PasswordStore("testtest".ToCharArray()); 
      PemReader pemReader = new PemReader(sr, passwordFinder); 


      Pkcs12Store store = new Pkcs12StoreBuilder().Build(); 
      X509CertificateEntry[] chain = new X509CertificateEntry[1]; 
      AsymmetricCipherKeyPair privKey = null; 

      object o; 
      while ((o = pemReader.ReadObject()) != null) 
      { 
       if (o is X509Certificate) 
       { 
        chain[0] = new X509CertificateEntry((X509Certificate)o); 
       } 
       else if (o is AsymmetricCipherKeyPair) 
       { 
        privKey = (AsymmetricCipherKeyPair)o; 
       } 
      } 

      store.SetKeyEntry("test", new AsymmetricKeyEntry(privKey.Private), chain); 
      FileStream p12file = File.Create("localhost.p12"); 
      store.Save(p12file, "testtest".ToCharArray(), new SecureRandom()); 
      p12file.Close(); 
     } 
    } 

    class PasswordStore : IPasswordFinder 
    { 
     private char[] password; 

     public PasswordStore(
        char[] password) 
     { 
      this.password = password; 
     } 

     public char[] GetPassword() 
     { 
      return (char[])password.Clone(); 
     } 

    } 
} 

你可能需要的东西为IPasswordFinder更微妙的一点,如果你想办理证书正确链接。 有关更多高级功能,您可以在BouncyCastle examples中找到更多详细信息。