我有一个X509Certificate2变量,我正在尝试将该变量的私钥转换为RSACryptoServiceProvider
RSACryptoServiceProvider pkey = (RSACryptoServiceProvider)cert.PrivateKey;
但是我得到这个例外。
System.InvalidCastException:'无法将类型为'System.Security.Cryptography.RSACng'的对象转换为类型为'System.Security.Cryptography.RSACryptoServiceProvider'。'
发生这种情况很奇怪,因为SO中的其他答案建议的程序与我的相同,但我得到了例外。有什么解决办法吗?
答案 0 :(得分:2)
只是要注意,还有一种扩展方法可以使用:
using System.Security.Cryptography.X509Certificates;
...
//certificate is a X509Certificate2
using (var rsa = certificate.GetRSAPrivateKey())
{
//the var rsa is an RSA object
//...
}
答案 1 :(得分:1)
因此,在评论中进行了几次尝试和讨论之后,我提出了以下解决方案。
RSA rsa = (RSA)cert.PrivateKey;
(cert.PrivateKey as RSACng).Key.SetProperty(
new CngProperty(
"Export Policy",
BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),
CngPropertyOptions.Persist));
RSAParameters RSAParameters = rsa.ExportParameters(true);
AsymmetricCipherKeyPair keypair = DotNetUtilities.GetRsaKeyPair(RSAParameters);
问题是变量rsa
不可导出。要更改此设置,我为导出策略设置了一个新的CngProperty。现在可以正常运行
答案 2 :(得分:0)
在我的情况下,尝试将本地商店证书转换为RSACryptoServiceProvider
时发生了相同的问题,如下所示:
RSACryptoServiceProvider encryptProvider =
certificate.PrivateKey as RSACryptoServiceProvider;
使用RSA
而不是RSACryptoServiceProvider
修复了问题。
在此处放置说明,以防有人好奇该怎么做))。
要将某些证书存储到您的计算机中,请打开 Visual Studio Developer命令并输入以下内容:
makecert -n "CN=JohnDoe" -sr currentuser -ss someCertStore
...您可以在其中指定和值,而不是“ JohnDoe”和“ demoCertStore”。
现在,您可以使用以下代码从本地证书存储区访问证书:
public class Program
{
static void DumpBytes(string title, byte[] bytes)
{
Console.Write(title);
foreach (byte b in bytes)
{
Console.Write("{0:X} ", b);
}
Console.WriteLine();
}
static void Main(string[] args)
{
// This will convert our input string into bytes and back
var converter = new ASCIIEncoding();
// Get a crypto provider out of the certificate store
// should be wrapped in using for production code
var store = new X509Store("someCertStore", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
// should be wrapped in using for production code
X509Certificate2 certificate = store.Certificates[0];
RSA rsa = (RSA)certificate.PrivateKey;
(certificate.PrivateKey as RSACng)?.Key.SetProperty(
new CngProperty(
"Export Policy",
BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),
CngPropertyOptions.Persist));
string messageToSign = "This is the message I want to sign";
Console.WriteLine("Message: {0}", messageToSign);
byte[] messageToSignBytes = converter.GetBytes(messageToSign);
// need to calculate a hash for this message - this will go into the
// signature and be used to verify the message
// Create an implementation of the hashing algorithm we are going to us
// should be wrapped in using for production code
DumpBytes("Message to sign in bytes: ", messageToSignBytes);
HashAlgorithm hasher = new SHA1Managed();
// Use the hasher to hash the message
byte[] hash = hasher.ComputeHash(messageToSignBytes);
DumpBytes("Hash for message: ", hash);
// Now sign the hash to create a signature
byte[] signature = rsa.SignHash(hash, HashAlgorithmName.SHA1, RSASignaturePadding.Pss);
DumpBytes("Signature: ", messageToSignBytes);
// Now use the signature to perform a successful validation of the mess
bool validSignature = rsa.VerifyHash(hash: hash,
signature: signature,
hashAlgorithm: HashAlgorithmName.SHA1,
padding: RSASignaturePadding.Pss);
Console.WriteLine("Correct signature validated OK: {0}", validSignature);
// Change one byte of the signature
signature[0] = 99;
// Now try the using the incorrect signature to validate the message
bool invalidSignature = rsa.VerifyHash(hash: hash,
signature: signature,
hashAlgorithm: HashAlgorithmName.SHA1,
padding: RSASignaturePadding.Pss);
Console.WriteLine("Incorrect signature validated OK: {0}", invalidSignature);
Console.ReadKey();
}
答案 3 :(得分:0)
通过仅使用正确的导出策略创建证书,就可以完全避免设置导出策略的代码。我使用New-SelfSignedCertificate PowerShell实用程序创建了一个可从创建之初导出的证书。
PS C:> New-SelfSignedCertificate -CertStoreLocation“ Cert:\ CurrentUser \”-主题“ CN = JUSTIN” -KeyExportPolicy可导出
这不需要:
(certificate.PrivateKey as RSACng)?.Key.SetProperty(new CngProperty("Export Policy", BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),CngPropertyOptions.Persist));