5

PKCS12 ファイル (PFX) に変換したい.PEM ファイルがあり、次の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セキュリティ ライブラリの使用: PEM ファイルから証明書オブジェクトを作成できますが、ドキュメントには次のように記載されています。

備考 この実装は、PEM ファイルからの証明書のみを読み取ります。秘密鍵が存在する場合、証明書ファイルから秘密鍵を読み取りません。

だから、それは私を助けません。その秘密鍵も必要です。

基本的に、PEM>PFX に移行するための OpenSSL コマンド ライン ツール操作をコードで再作成する必要があります。

これを行う簡単な方法はありますか?

4

1 に答える 1

5

BouncyCastleを使用できます(.NET について言及したため、C# を想定しています)。

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 の例で詳細を確認できる場合があります。

于 2010-06-23T00:47:11.643 に答える