Getting Exception quot;Invalid Provider type specifiedquot; or quot;Key does not existquot; while getting Private key from X509Certificate2 Occasionally(偶尔从X509证书2获取私钥时,获取异常或指定的提供程序类型无效。密钥不存在。)
问题描述
我在尝试从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获取私钥时,获取异常或指定的提供程序类型无效。密钥不存在。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:偶尔从X509证书2获取私钥时,获取异常或指定的提供程序类型无效。密钥不存在。
基础教程推荐
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- WPF 模态进度窗口 2022-01-01
