问题描述
我在尝试从X509证书2获取私钥时遇到以下异常之一:
System.Security.Cryptography.CryptographicException:指定的提供程序类型无效。
或
以下代码行中不存在System.Security.Cryptography.CryptographicException:密钥:RSACryptoServiceProvider rsaKey=(RSACryptoServiceProvider)digiSignCert.PrivateKey;
堆栈跟踪:
System.Security.Cryptography.CryptographicException:密钥不存在。在System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType的密钥类型、Csp参数参数、布尔随机密钥容器、Int32dwKeySize、SafeProvHandle和SafeProvHandle、SafeKeyHandle和SafeKeyHandle)在System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()的System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32的密钥大小、Csp参数参数、布尔的用法默认密钥大小)在System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()的Api.cerficateUtil.GetSignedXML(字符串xml,X509证书2 PriateCert)
编码:
public static RSACryptoServiceProvider rsaKey = null;
public X509Certificate2 _PrivateCert;
public APISearch()
{
byte[] privateCert = null;//We get the actual certificate file data here
GetPrivateCerificate(privateCert, "abc@123");
GetSignedXml(_PrivateCert);
}
public void GetPrivateCerificate(byte[] privateCert, string pwd)
{
_PrivateCert = new X509Certificate2(privateCert, pwd, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
}
public void GetSignedXml(X509Certificate2 privateCert)
{
rsaKey = (RSACryptoServiceProvider)privateCert.PrivateKey; //Occassional Exception
}
预期结果:(RSACryptoServiceProvider)privateCert.PrivateKey
应始终生成私钥。
实际结果:有时会在该行抛出上述异常:
rsaKey = (RSACryptoServiceProvider)privateCert.PrivateKey;
推荐答案
RSACryptoServiceProvider
是一种通过Windows加密API(CAPI)库执行的类型。当.NET第一次被创建时,CAPI是新的,并且总是正确的答案(在Windows上)。从Windows Vista开始,有一个新的库:密码学:下一代(CNG)。出于兼容性考虑,CNG了解如何使用CAPI。但CAPI不能"做CAPI",不能"懂CNG"。您看到的例外情况是,当PFX指示私钥应该通过CNG存储时(或者店内证书指示其私钥通过CNG存储)。
当.NET框架添加RSACng
时,确定已经有太多人编写了(RSACryptoServiceProvider)cert.PrivateKey
行,因此该属性永远不能返回RSACng
实例。相反,在.NET 4.6中创建了新的(扩展)方法:cert.GetRSAPublicKey()
和cert.GetRSAPrivateKey()
,它们返回RSA
而不是AsymmetricAlgorithm
。在.NET 4.6中,RSA基类也得到了增强,可以将签名/验证和加密/解密操作向下移动(尽管使用了不同的签名,因为自编写CAPI以来RSA获得了新的选项)。
预期结果:(RSACryptoServiceProvider)privateCert.PrivateKey
应始终生成私钥。
实际情况是cert.PrivateKey
(和cert.PublicKey.Key
)是被软否决的。你不应该再叫它/他们了。RSA(4.6)、ECDSA(4.6.1)和DSA(4.6.2)都有GET[算法]{Public|Private}密钥方法。
(RSACryptoServiceProvider)cert.PrivateKey
=>cert.GetRSAPrivateKey()
rsaCSP.Encrypt(data, false)
=>rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1)
rsaCSP.Encrypt(data, true)
=>rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA1)
rsaCSP.SignData(data, "SHA256")
=>rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
Decrypt
、SignHash
、VerifyData
、VerifyHash
相似;ECDsa
和DSA
相似。
这篇关于偶尔从X509证书2获取私钥时,获取异常或指定的提供程序类型无效。密钥不存在。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!