2010-06-22 40 views
3

J'ai un .PEM file que je veux convertir un fichier PKCS12 (PFX), et je sais que je peux facilement y parvenir en utilisant la commande openssl suivante:Convertir un certificat .PEM à .PFX par programme en utilisant OpenSSL

Create a PKCS#12 file: 

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

ce qui est génial, mais je voudrais le faire par programme en utilisant OpenSSL appels. Malheureusement, la documentation d'OpenSSL est loin d'être idéale.

Je l'ai regardé en faisant cela à l'aide d'autres bibliothèques:

En utilisant .NET: Je peux créer un objet X509Certificate2 à partir d'un fichier PEM, mais attrape seulement le premier certificat et ne tient pas compte dans le fichier PEM toute CA intermédiaire .

En utilisant Mentalis.org Security Library: Je peux créer un objet de certificat à partir d'un fichier PEM, mais je vois ce qui suit dans la documentation:

Remarques Cette mise en œuvre se lit comme suit seulement certificats de fichiers PEM. Il ne lit pas la clé privée du fichier de certificat , le cas échéant.

Donc, cela ne m'aide pas. J'ai aussi besoin de cette clé privée.

J'ai fondamentalement besoin de recréer l'opération de l'outil de ligne de commande OpenSSL pour aller PEM> PFX, mais dans le code.

Existe-t-il un moyen plus simple de le faire?

Répondre

4

Vous pouvez utiliser BouncyCastle (en supposant que C#, car vous avez mentionné .NET).

Disons que localhost.pem ici contient à la fois le certificat et la clé privée, quelque chose comme cela devrait fonctionner:

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

    } 
} 

Vous aurez probablement besoin de quelque chose un peu plus subtile pour la IPasswordFinder et si vous voulez gérer le certificat chaînes correctement. Pour plus de fonctionnalités avancées, vous pouvez trouver plus de détails dans le BouncyCastle examples.