如何从PEM文件私有密钥?密钥、文件、PEM

2023-09-02 11:56:29 作者:你亲爱的爹

我有一个包括公钥和私钥SSL数据传输这样的.PEM文件:

i have a .PEM file that includes public key and a private key for SSL data transfer like this:

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

当我想要加载通过以下code中的.PEM文件:

when i want to load the .PEM file by the following code:

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

我得到一个异常,说:找不到请求的对象 ,有完整的堆栈:

i get an exception that says: "Cannot find the requested object." , with full stack:

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:ProjectsDLLTestDLLTestSSL_Test.cs:line 165
       at DLLTest.SSL_Test.Run() in E:ProjectsDLLTestDLLTestSSL_Test.cs:line 21
       at DLLTest.Program.Main(String[] args) in E:ProjectsDLLTestDLLTestProgram.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: 

如果我换地方私钥部分和公共密钥部分中,code ++工程和负载数据,我可以从对象,如只公钥信息。证书中issuerName, 其HasPrivateKey是假的。为什么?是我误解和做错了什么吗?

if i swap place of private key section and public key section, the code works and load data, and i can get just public key info from the object, eg. IssuerName, and its HasPrivateKey is false. why? am i misunderstood and doing wrong something?

推荐答案

有一个的文章在code计划有所有code,你需要做到这一点。这只是一对夫妇的类,所以它是一个轻量级的解决方案。

There's an article on the Code Project that has all the code you need to do this. It's just a couple of classes so it's a light-weight solution.

要获取文件中的密钥和证书的顺序的字节证书或从PEM密钥文件下面的方法将工作无关。

To get the bytes for either a certificate or a key from the PEM file the following method will work, regardless of the order of the key and certificate in the file.

 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) + header.Length;
     var end = pemString.IndexOf(footer, start, StringComparison.Ordinal) - start;

     if( start < 0 || end < 0 )
     {
        return null;
     }

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

加载PEM文件转换成字符串,并调用上面的方法来获取重新present证书的字节。接下来,您将获得的字节到X509Certificate2的构造函数:

Load the PEM file into a string and call the method above to get the bytes that represent the certificate. Next you pass the obtained bytes to the constructor of an X509Certificate2 :

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

加载(RSA)从PEM文件私钥是一个比较复杂一点,但你会发现,在上面提到的文章,以及使用支持 Crypto.De codeRsaPrivateKey 方法。