C# 仅使用Bouncy Castle读取PEM RSA公钥
我正在尝试使用C#读入只包含RSA公钥的C# 仅使用Bouncy Castle读取PEM RSA公钥,c#,bouncycastle,public-key,pem,C#,Bouncycastle,Public Key,Pem,我正在尝试使用C#读入只包含RSA公钥的.pem文件。我无权访问私钥信息,我的应用程序也不需要它。文件myprivatekey.pem以开头 ----开始公钥--- 以 ----结束公钥--- 我目前的代码如下: Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair; using (var reader = File.OpenText(@"c:\keys\myprivatekey.pem")) keyPa
.pem
文件。我无权访问私钥信息,我的应用程序也不需要它。文件myprivatekey.pem
以开头
----开始公钥---
以
----结束公钥---
我目前的代码如下:
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.bounchycastle.Crypto.asymmetricipherkeypair”
当没有私钥信息可用时,如何使用Bouncy Castle的
PemReader
仅读取公钥?以下代码将从给定文件名读取公钥。对于任何生产代码,都应更改异常处理。此方法返回一个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;
}
在回答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));
下面是一个可能的解决方案,它可以将公共和私有PEM文件读入RSACryptServiceProvider:
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());
}
}
公共类读卡器
{
公共静态RSACryptServiceProvider GetRSProviderFromPEM(字符串PEMSR)
{
CspParameters CspParameters=新的CspParameters();
cspParameters.KeyContainerName=“MyKeyContainer”;
RSACryptoServiceProvider rsaKey=新的RSACryptoServiceProvider(cspParameters);
Func MakePublicRCSP=(RSACryptServiceProvider rcsp,RsaKeyParameters rkp)=>
{
rsapameters rsapameters=DotNetUtilities.ToRSAParameters(rkp);
rcsp.进口参数(RSA参数);
返回密钥;
};
Func MakePrivateCSP=(RSACryptServiceProvider rcsp,RsaPrivateCrtKeyParameters rkp)=>
{
rsapameters rsapameters=DotNetUtilities.ToRSAParameters(rkp);
rcsp.进口参数(RSA参数);
返回密钥;
};
PemReader=新PemReader(新StringReader(PEMSR));
object kp=reader.ReadObject();
//如果对象具有私有/公共属性,则我们具有私有PEM
return(kp.GetType().GetProperty(“Private”)!=null)?MakePrivateCSP(rsaKey,(RsaPrivateCrtKeyParameters)(((不对称密码对)kp.Private)):MakePublicRCSP(rsaKey,(RsaKeyParameters)kp);
}
公共静态RSACryptServiceProvider GetRSProviderFromPEMFile(字符串pemfile)
{
返回GetRSAProviderFromPem(File.ReadAllText(pemfile.Trim());
}
}
希望这对某人有所帮助。请尝试以下代码:
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;
编辑:
看起来这取决于您使用的密钥文件的类型。对于ssh-keygen密钥,私钥的类型似乎为asymmetricipherkeypair
,但对于openssl密钥,私钥的类型为RsaPrivateCrtKeyParameters
Bryan Jyh Herng Chong的答案似乎不再适用于我(至少对于Bouncy Castle v1.8.5版而言)。看起来,
kp.GetType().GetProperty(“Private”)
对于公钥和私钥PEM对象的设置不再不同。另外,使用PemReader.ReadObject()
返回的对象现在直接是rsaprovatecrtkeyparameters
对象,因此不再需要首先转换asymmetricipherkeypair
对象
我把那句话改成了这句话,效果很好:
return (kp.GetType() == typeof(RsaPrivateCrtKeyParameters)) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)kp)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
而不是:
keyPair = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();
使用:
由于您只使用公钥,而实际上没有一对密钥(公钥和私钥),因此不能将其转换为“AsymmetricHipherKeyPair”,您应该将其转换为“AsymmetricKeyParameter”。单个公钥不是密钥对。密钥对是公钥和私钥。这也可以用来读取私钥吗?然后在密码函数中传入false,例如:cipher.Init(false,privatekey)。对于Linux/.NET标准,我只是使用无参数构造函数创建了一个新的RSACryptServiceProvider。
keyPair = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();