Конвертируйте сертификат .PEM в .PFX программно, используя OpenSSL - PullRequest
3 голосов
/ 23 июня 2010

У меня есть .PEM файл , который я хочу преобразовать в файл PKCS12 (PFX), и я знаю, что могу легко сделать это, используя следующую команду openssl:

Create a PKCS#12 file:

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

Это здорово, но я бы хотел сделать это программно, используя OpenSSL вызовы.К сожалению, документация для OpenSSL не идеальна.

Я пытался сделать это, используя другие библиотеки:

Используя .NET: я могу создать объект X509Certificate2 из файла PEM, но этотолько захватывает первый сертификат и игнорирует любые промежуточные CA в файле PEM.

Использование Mentalis.org Библиотека безопасности: я могу создать объект сертификата из файла PEM, но я вижу следующеев документации:

Замечания Эта реализация только читает сертификаты из файлов PEM.Он не читает секретный ключ из файла сертификата, если он есть.

Так что это мне не поможет.Мне также нужен этот закрытый ключ.

Мне нужно пересоздать операцию инструмента командной строки OpenSSL для перехода PEM> PFX, но в коде.

Есть ли более простой способ сделать это?

1 Ответ

4 голосов
/ 23 июня 2010

Вы можете использовать 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 .

...