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

发布于 2024-09-06 19:22:40 字数 879 浏览 11 评论 0原文

我有一个 .PEM 文件,我想将其转换为 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 文件创建证书对象,但我在文档中看到以下内容:

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

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

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

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

I've got a .PEM file that I want to convert to a PKCS12 file (PFX), and I know I can easily accomplish this using the following openssl command:

Create a PKCS#12 file:

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

Which is great, but I'd like to do this programmatically using OpenSSL calls. Unfortunately, documentation for OpenSSL is less than ideal.

I've looked into doing this using other libraries:

Using .NET: I can create a X509Certificate2 object from a PEM file, but this only grabs the first certificate and ignores any intermediate CA's in the PEM file.

Using Mentalis.org Security Library: I can create a Certificate object from a PEM file, but I see the following in the documentation:

Remarks
This implementation only reads
certificates from PEM files. It does
not read the private key from the
certificate file, if one is present.

So, that doesn't help me. I need that private key too.

I basically need to recreate the OpenSSL command line tool operation for going PEM>PFX, but in code.

Is there an easier way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

古镇旧梦 2024-09-13 19:22:40

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

You could use BouncyCastle (assuming C#, because you mentioned .NET).

Let's say localhost.pem here contains both the certificate and the private key, something like this should work:

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

    }
}

You'll probably need something a bit more subtle for the IPasswordFinder and if you want to handle certificate chains correctly.
For more advanced features, you may be able to find more details in the BouncyCastle examples.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文