2012-07-05 345 views
8

我正嘗試使用C#讀取僅包含RSA公鑰的.pem文件。我無權訪問私鑰信息,我的應用程序也不需要它。文件myprivatekey.pem文件開始使用Bouncy Castle閱讀PEM RSA公鑰僅使用Bouncy Castle

-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----結束。

我當前的代碼如下:

Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair; 

    using (var reader = File.OpenText(@"c:\keys\myprivatekey.pem")) 
     keyPair = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject(); 

然而代碼拋出InvalidCastException與消息

無法轉換類型 「Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters的對象'鍵入 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'。

如何在沒有私鑰信息時使用Bouncy Castle的PemReader來只讀公鑰?

+2

單個公鑰不是密鑰對。密鑰對是公鑰*和*私鑰。 – 2012-07-07 14:56:04

回答

14

下面的代碼只會讀取一個只有給定文件名的公鑰。任何生產代碼都應該更改異常處理。此方法返回AsymetricKeyParameter

public Org.BouncyCastle.Crypto.AsymmetricKeyParameter ReadAsymmetricKeyParameter(string pemFilename) 
{ 
    var fileStream = System.IO.File.OpenText (pemFilename); 
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader (fileStream); 
    var KeyParameter = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pemReader.ReadObject(); 
    return KeyParameter; 
} 
+0

這可以用來讀取私鑰嗎?然後在密碼函數中傳遞false,例如:cipher.Init(false,privatekey)。我沒有運氣就試過這個。 – c0d3Junk13 2013-03-25 20:48:53

2

在回答c0d3Junk13,我有同樣的問題了PEM私鑰和我花了一下午找到使用C#BouncyCastle的版本1.7和Visual Studio 2013的桌面快車解決方案。不要忘了這個項目引用添加到BouncyCastle.Crypto.dll

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Collections; 
using System.IO; 
using Org.BouncyCastle.Asn1.X509; 
using Org.BouncyCastle.Asn1.Pkcs; 
using Org.BouncyCastle.Crypto.Digests; 
using Org.BouncyCastle.Crypto.Parameters; 
using Org.BouncyCastle.Crypto.Signers; 
using Org.BouncyCastle.X509; 
using Org.BouncyCastle.Math; 
using Org.BouncyCastle.Math.EC; 
using Org.BouncyCastle.Utilities.Collections; 
using Org.BouncyCastle.Utilities.Encoders; 
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Engines; 
using Org.BouncyCastle.OpenSsl; 

/* 
    For an Active Directory generated pem, strip out everything in pem file before line: 
    "-----BEGIN PRIVATE KEY-----" and re-save. 
*/ 
string privateKeyFileName = @"C:\CertificateTest\CS\bccrypto-net-1.7-bin\private_key3.pem"; 

TextReader reader = File.OpenText(privateKeyFileName); 

Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters key; 

using (reader = File.OpenText(privateKeyFileName)) 
{ 
    key = (Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)new PemReader(reader).ReadObject(); 
} 

cipher.Init(false, key); 

//Decrypting the input bytes 

byte[] decipheredBytes = cipher.ProcessBlock(cipheredBytes, 0, cipheredBytes.Length); 

MessageBox.Show(Encoding.UTF8.GetString(decipheredBytes)); 
1

這裏是一個可能的解決方案,它讀取公共和私人PEM文件到的RSACryptoServiceProvider:

public class PemReaderB 
{ 
    public static RSACryptoServiceProvider GetRSAProviderFromPem(String pemstr) 
    { 
     CspParameters cspParameters = new CspParameters(); 
     cspParameters.KeyContainerName = "MyKeyContainer"; 
     RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParameters); 

     Func<RSACryptoServiceProvider, RsaKeyParameters, RSACryptoServiceProvider> MakePublicRCSP = (RSACryptoServiceProvider rcsp, RsaKeyParameters rkp) => 
     { 
      RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp); 
      rcsp.ImportParameters(rsaParameters); 
      return rsaKey; 
     }; 

     Func<RSACryptoServiceProvider, RsaPrivateCrtKeyParameters, RSACryptoServiceProvider> MakePrivateRCSP = (RSACryptoServiceProvider rcsp, RsaPrivateCrtKeyParameters rkp) => 
     { 
      RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp); 
      rcsp.ImportParameters(rsaParameters); 
      return rsaKey; 
     }; 

     PemReader reader = new PemReader(new StringReader(pemstr)); 
     object kp = reader.ReadObject(); 

     // If object has Private/Public property, we have a Private PEM 
     return (kp.GetType().GetProperty("Private") != null) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)kp).Private)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp); 
    } 

    public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile) 
    { 
     return GetRSAProviderFromPem(File.ReadAllText(pemfile).Trim()); 
    } 
} 

希望這可以幫助別人。

相關問題