C# 仅使用 Bouncy Castle 读取 PEM RSA 公钥
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11346200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading PEM RSA Public Key Only using Bouncy Castle
提问by cytinus
I am trying to use C# to read in a .pemfile that contains only a RSA public key. I do not have access to the private key information, nor does my application require it. The file myprivatekey.pemfile begins with
我正在尝试使用 C# 读取.pem仅包含 RSA 公钥的文件。我无权访问私钥信息,我的应用程序也不需要它。文件myprivatekey.pem文件以
-----BEGIN PUBLIC KEY-----and ends with
-----END PUBLIC KEY-----.
-----BEGIN PUBLIC KEY-----并以
-----END PUBLIC KEY-----.
My current code is as follows:
我目前的代码如下:
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();
However the code throws an InvalidCastExceptionwith the message
但是代码抛出一个InvalidCastException带有消息的
Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'.
无法将类型为“Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters”的对象转换为类型“Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair”。
How can I use Bouncy Castle's PemReaderto read only a public key, when no private key information is available?
PemReader当没有可用的私钥信息时,如何使用 Bouncy Castle仅读取公钥?
采纳答案by cytinus
The following code will read a public key only given a filename. The exception handling should be changed for any production code. This method returns an AsymetricKeyParameter.
以下代码将仅读取给定文件名的公钥。任何生产代码的异常处理都应该更改。此方法返回一个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;
}
回答by Bertrand_Szoghy
In answer to c0d3Junk13, I had the same issue for a PEM private key and it took me all afternoon to find the solution using the C# BouncyCastle Version 1.7 and Visual Studio 2013 Desktop Express. Don't forget to add the project reference to BouncyCastle.Crypto.dll
在回答 c0d3Junk13 时,我在 PEM 私钥上遇到了同样的问题,我花了整个下午才找到使用 C# BouncyCastle 1.7 版和 Visual Studio 2013 Desktop Express 的解决方案。不要忘记将项目引用添加到 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));
回答by Bryan Jyh Herng Chong
Here's a possible solution that reads both public and private PEM files into RSACryptoServiceProvider:
这是将公共和私有 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());
}
}
Hope this helps someone.
希望这可以帮助某人。
回答by Arun Singh
Try the following code:
试试下面的代码:
Using Org.BouncyCastle.Crypto;
string path = HttpContext.Current.Server.MapPath(@"~\key\ABCD.pem");
AsymmetricCipherKeyPair Key;
TextReader tr = new StreamReader(@path);
PemReader pr = new PemReader(tr);
Key = (AsymmetricCipherKeyPair)pr.ReadObject();
pr.Reader.Close();
tr.Close();
AsymmetricKeyParameter keaa = Key.Public;
回答by jzfizzler
EDIT:
It looks like this depends on what type of key file you are using. For ssh-keygenkeys, the private key appears to have a type of AsymmetricCipherKeyPair, but for opensslkeys, the private key has a type of RsaPrivateCrtKeyParameters.
编辑:看起来这取决于您使用的密钥文件类型。对于ssh-keygen密钥,私钥的类型似乎是AsymmetricCipherKeyPair,但对于openssl密钥,私钥的类型是RsaPrivateCrtKeyParameters。
Bryan Jyh Herng Chong's answer no longer appears to work for me (at least with Bouncy Castle version v1.8.5). It appears kp.GetType().GetProperty("Private")is no longer set differently for public vs private key PEM objects. It also appears that the object returned using PemReader.ReadObject()is now directly a RsaPrivateCrtKeyParametersobject, so there's no longer a need to cast through a AsymmetricCipherKeyPairobject first.
Bryan Jyh Herng Chong 的回答似乎不再适合我(至少对于 Bouncy Castle 版本 v1.8.5)。kp.GetType().GetProperty("Private")公钥和私钥 PEM 对象的设置似乎不再不同。似乎使用返回的对象PemReader.ReadObject()现在直接是一个RsaPrivateCrtKeyParameters对象,因此不再需要首先通过AsymmetricCipherKeyPair对象进行转换。
I changed that line to this and it worked like a charm:
我把那行改成这样,它的作用就像一个魅力:
return (kp.GetType() == typeof(RsaPrivateCrtKeyParameters)) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)kp)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);

