38

次のようなSSLデータ転送用の公開鍵と秘密鍵を含む.PEMファイルがあります。

-----BEGIN RSA PRIVATE KEY-----
      private key data
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
      public key data
-----END CERTIFICATE-----

次のコードで .PEM ファイルをロードしたい場合:

X509Certificate2 xx = new X509Certificate2("c:\\myKey.pem");

「要求されたオブジェクトが見つかりません」という例外が発生します。、フルスタック:

System.Security.Cryptography.CryptographicException was unhandled
  Message=Cannot find the requested object.

  Source=mscorlib
  StackTrace:
       at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
       at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertFileType(String fileName)
       at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
       at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName)
       at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName)
       at DLLTest.SSL_Test.test() in E:\Projects\DLLTest\DLLTest\SSL_Test.cs:line 165
       at DLLTest.SSL_Test.Run() in E:\Projects\DLLTest\DLLTest\SSL_Test.cs:line 21
       at DLLTest.Program.Main(String[] args) in E:\Projects\DLLTest\DLLTest\Program.cs:line 21
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

秘密鍵セクションと公開鍵セクションの場所を交換すると、コードが機能してデータがロードされ、オブジェクトから公開鍵情報だけを取得できます。IssuerName であり、その HasPrivateKey は false です。なぜ?私は誤解していて、何か間違ったことをしていますか?

4

7 に答える 7

39

これを行うために必要なすべてのコードを含むコード プロジェクトに関する記事があります。これはほんの数クラスなので、軽量のソリューションです。

PEM ファイルから証明書またはキーのバイトを取得するには、ファイル内のキーと証明書の順序に関係なく、次の方法が機能します。

 byte[] GetBytesFromPEM( string pemString, string section )
 {
     var header = String.Format("-----BEGIN {0}-----", section);
     var footer = String.Format("-----END {0}-----", section);

     var start= pemString.IndexOf(header, StringComparison.Ordinal);
     if( start < 0 )
        return null;

     start += header.Length;
     var end = pemString.IndexOf(footer, start, StringComparison.Ordinal) - start;

     if( end < 0 )
        return null;

     return Convert.FromBase64String( pemString.Substring( start, end ) );
 }

PEM ファイルを文字列に読み込み、上記のメソッドを呼び出して、証明書を表すバイトを取得します。次に、取得したバイトを X509Certificate2 のコンストラクターに渡します。

 var pem = System.IO.File.ReadAllText( "c:\\myKey.pem" );
 byte[] certBuffer = GetBytesFromPEM( pem, "CERTIFICATE" );
 var certificate = new X509Certificate2( certBuffer );

PEM ファイルから (RSA) 秘密鍵をロードするのはもう少し複雑ですが、上記の記事でもこのCrypto.DecodeRsaPrivateKey方法を使用してサポートされています。

于 2012-05-08T11:51:57.690 に答える
19

私の知る限り、.NET フレームワークは PEM をサポートしていません。

-----BEGIN CERTIFICATE ----------END CERTIFICATE-----X509Certificate行の間の base64 文字列を抽出し、それを aとそこから作成します。byte[]X509Certificate

簡単な解決策は、Mono.Security のX509Certificate.csからコードをコピーして貼り付けることです。

byte[]秘密鍵を取得しても RSA インスタンスを再構築するのにあまり役に立たないため、秘密鍵を取得するのは少し注意が必要です (PEM ヘッダーに RSA と記載されているため、これを想定できます)。

今回は、Mono.Security のPKCS8.csファイルからコピー アンド ペーストし、decode メソッドを sioly で呼び出します。

免責事項: 私は上記の Mono コードの主な作成者であり、すべて MIT.X11 ライセンスの下で利用できます。

于 2011-10-13T01:39:13.590 に答える
-1

.NET (ただし Java) はわかりませんが、答えは同じはずです。
pem ファイルには、証明書と秘密鍵の両方が含まれています。
これは、OpenSSL での通常のエクスポートです。
Javaでオブジェクトをインスタンス化するX509Certificateには、ファイルの次の部分のみを使用します。

-----BEGIN CERTIFICATE-----
証明書データ
-----END CERTIFICATE-----

.NET でも同じはずです。
ファイルをロードして、PEM のその部分をロードするだけです。

秘密鍵についても同じことを行います。
Java では、対応するオブジェクト、つまり PrivateKey を使用してロードします。
.NET に適したものを使用してください

于 2011-09-14T08:13:30.047 に答える
-2

私は同じ問題に遭遇し、以下のような解決策を見つけました:

まず、このツールで prkey.pem を prkey.xml に変換します // https://superdry.apphb.com/tools/online-rsa-key-converter

         var dataString = "test";

        byte[] dataToEncrypt = Encoding.UTF8.GetBytes(dataString);

        RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
        provider.FromXmlString(File.ReadAllText("C:\prkey.xml"));
        byte[] signedBytes = provider.SignData(dataToEncrypt, new SHA256CryptoServiceProvider());

        textBox3.Text = BitConverter.ToString(signedBytes);
于 2019-03-05T06:31:30.617 に答える