首页 文章

使用OpenSSL以编程方式将.PEM证书转换为.PFX

提问于
浏览
3

我有一个.PEM file,我想转换为PKCS12文件(PFX),我知道我可以使用以下 openssl 命令轻松完成此操作:

创建PKCS#12文件:

openssl pkcs12 -export -in file.pem -out file.p12 -name“我的证书”

这很棒,但我想使用OpenSSL调用以编程方式执行此操作 . 不幸的是,OpenSSL的文档不太理想 .

我已经研究过使用其他库来做这件事:

使用.NET:我可以从PEM文件创建X509Certificate2对象,但这只会抓取第一个证书并忽略PEM文件中的任何中间CA.

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

备注此实现仅从PEM文件中读取证书 . 它不会从证书文件中读取私钥(如果存在) .

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

我基本上需要重新创建用于运行PEM> PFX的OpenSSL命令行工具操作,但是在代码中 .

有更简单的方法吗?

1 回答

  • 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中找到更多详细信息 .

相关问题