2012-07-05 34 views
8

Tôi đang cố gắng sử dụng C# để đọc trong tệp .pem chỉ chứa khóa công cộng RSA. Tôi không có quyền truy cập vào thông tin khóa cá nhân, cũng như ứng dụng của tôi không yêu cầu nó. Tệp tin myprivatekey.pem bắt đầu bằngĐọc Khóa công cộng PEM RSA Chỉ sử dụng Lâu đài Bouncy

-----BEGIN PUBLIC KEY----- và kết thúc bằng -----END PUBLIC KEY-----.

mã hiện tại của tôi là như sau:

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(); 

Tuy nhiên mã ném một InvalidCastException với thông điệp

Không thể cast đối tượng kiểu 'Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters 'để nhập ' Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair '.

Tôi làm cách nào để sử dụng Bouncy Castle's PemReader để chỉ đọc khóa công khai khi không có thông tin khóa riêng tư?

+2

Một khóa công khai duy nhất không phải là một cặp khóa. Một cặp khóa là khóa công khai * và * một khóa riêng. –

Trả lời

14

Mã sau sẽ đọc khóa công cộng chỉ được cung cấp tên tệp. Việc xử lý ngoại lệ phải được thay đổi đối với bất kỳ mã sản xuất nào. Phương thức này trả về một số 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

Điều này có thể được sử dụng để đọc một khóa riêng tư không? Sau đó, chỉ cần nhập sai trong hàm mật mã như: cipher.Init (false, privatekey). Tôi đã thử điều này mà không có may mắn. – c0d3Junk13

2

Trong câu trả lời cho c0d3Junk13, tôi đã cùng một vấn đề cho một khóa riêng PEM và nó đã cho tôi tất cả các buổi chiều để tìm giải pháp bằng cách sử dụng C# BouncyCastle Phiên bản 1.7 và Visual Studio 2013 Desktop Express. Đừng quên để thêm tài liệu tham khảo dự án để 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

Dưới đây là một giải pháp khả thi mà đọc file PEM cả công cộng và tư nhân vào 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()); 
    } 
} 

Hope this helps một ai đó.

Các vấn đề liên quan