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

5

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

Create a PKCS#12 file:

 openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate"
这很好,但我想使用OpenSSL调用程序来以编程方式完成。不幸的是,OpenSSL的文档不太理想。
我已经研究过使用其他库来完成此操作:
使用.NET:我可以从PEM文件创建X509Certificate2对象,但这仅获取第一个证书,并忽略PEM文件中的任何中间CA。
使用Mentalis.org Security Library:我可以从PEM文件创建Certificate对象,但在文档中看到以下内容:
备注 此实现仅从PEM文件中读取证书。如果存在私钥,则不会从证书文件中读取私钥。
所以,这对我没有帮助。我也需要私钥。
基本上,我需要在代码中重新创建OpenSSL命令行工具操作,以进行PEM>PFX转换。
有更简单的方法吗?
1个回答

5
您可以使用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中找到更多详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接