尝试加载证书的私钥时出现“指定的提供程序类型无效”CryptographicException
Posted
技术标签:
【中文标题】尝试加载证书的私钥时出现“指定的提供程序类型无效”CryptographicException【英文标题】:"Invalid provider type specified" CryptographicException when trying to load private key of certificate 【发布时间】:2014-04-30 04:20:44 【问题描述】:我正在尝试读取第三方服务提供商与我共享的证书的私钥,因此我可以使用它来加密某些 XML,然后再通过网络将其发送给他们。我在 C# 中以编程方式执行此操作,但我认为这是权限或配置错误问题,因此我将重点关注似乎最相关的事实:
我认为这个问题与代码无关;我的代码可以在其他计算机上运行,并且该问题会影响 Microsoft 的示例代码。 证书以 PFX 文件的形式提供,仅用于测试目的,因此它还包含一个虚拟证书颁发机构。 使用 MMC.exe,我可以将证书导入本地计算机的个人存储中,然后将私钥的权限授予所有相关帐户,并将证书颁发机构拖放到受信任的根证书颁发机构中。李> 使用 C#,我可以加载证书(由其指纹识别)并使用X509Certificate2.HasPrivateKey
验证它是否具有私钥。但是,尝试读取密钥会导致错误。在 .NET 中,在尝试访问属性 X509Certificate2.PrivateKey
时会抛出 CryptographicException
并显示消息“指定的提供程序类型无效”。在 Win32 中,调用方法 CryptAcquireCertificatePrivateKey
返回等效的 HRESULT,NTE_BAD_PROV_TYPE
。
这与使用 Microsoft 自己的两个代码示例读取证书的私钥时也会发生的异常相同。
在当前用户的等效存储中(而不是本地计算机)安装相同的证书,可以成功加载私钥。
我在具有本地管理员权限的 Windows 8.1 上,我尝试在正常模式和提升模式下运行我的代码。使用 Windows 7 和 Windows 8 的同事已经能够从本地机器存储中加载相同证书的密钥。
我可以成功读取自签名 IIS 测试证书的私钥,该证书位于同一存储位置。
我已经针对 .NET 4.5(一些旧版本的框架报告了此错误)。
我认为这不是证书模板的问题,因为我希望这会同样影响本地计算机和当前用户存储?
与我的同事不同,我之前曾多次尝试以各种方式卸载和重新安装证书,包括通过 IIS 管理器以及来自同一颁发者的旧证书。我在 MMC 中看不到任何旧证书或重复证书的痕迹。但是,我确实有许多大小相同的私钥文件,根据上次写入时间,在我进行各种安装尝试后,这些文件肯定被遗忘了。这些位于以下位置,分别用于本地计算机和当前用户存储:
c:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
c:\Users\\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-[其余用户 ID]
那么,谁能告诉我是否:
最好使用 MMC 卸载证书,删除所有看起来像孤立私钥的文件,然后重新安装证书并重试? 还有其他我应该尝试手动删除的文件吗? 还有什么我应该尝试的吗?更新 - 添加了显示尝试读取私钥的代码示例:
static void Main()
// Exception occurs when trying to read the private key after loading certificate from here:
X509Store store = new X509Store("MY", StoreLocation.LocalMachine);
// Exception does not occur if certificate was installed to, and loaded from, here:
//X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select", "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.MultiSelection);
Console.WriteLine("Number of certificates: 01", scollection.Count, Environment.NewLine);
foreach (X509Certificate2 x509 in scollection)
try
Console.WriteLine("Private Key: 0", x509.HasPrivateKey ? x509.PrivateKey.ToXmlString(false) : "[N/A]");
x509.Reset();
catch (CryptographicException ex)
Console.WriteLine(ex.Message);
store.Close();
Console.ReadLine();
【问题讨论】:
我建议您发布相关代码... @DavidW 请参阅上面的代码示例,正如您所建议的那样 - 但是,我认为这几乎肯定是证书配置错误或文件损坏的问题,而不是编码错误。 嗯......如果它与编程无关,很难诊断出这样的事情,但我做了一点窥探,发现了以下内容:blogs.msdn.com/b/alejacma/archive/2009/12/22/… 这听起来可能是相关的(晦涩的无效提供者类型除外。读取私钥).. @DavidW 好主意,谢谢!尝试访问可疑证书的密钥时,进程监视器中不会出现 ACCESS DENIED。不过,我确实证明了您的建议的概念,方法是拥有我的 IIS 测试证书的密钥文件并拒绝自己访问。 Process Monitor 检测到了,但抛出的异常略有不同:“Keyset 不存在”。 抱歉,我们从未找到解决方案,最终从 IT 部门获得了一个新系统。祝你好运! 【参考方案1】:我最近收到了两个新证书,在 Windows 8 和 Server 2012/2012 R2 上遇到了同样的问题。在 Windows 10 上,问题不再出现(但这对我没有帮助,因为在服务器上使用了操作证书的代码)。虽然 Joe Strommen 的解决方案原则上可行,但不同的私钥模型需要对使用证书的代码进行大量更改。我发现更好的解决方案是将私钥从 CNG 转换为 RSA,正如 Remy Blok here 所解释的那样。
Remy 使用 OpenSSL 和两个较旧的工具来完成私钥转换,我们希望将其自动化并开发了一个仅限 OpenSSL 的解决方案。给定MYCERT.pfx
和 CNG 格式的私钥密码 MYPWD
,以下是获取新的CONVERTED.pfx
的步骤,该新的CONVERTED.pfx
具有 RSA 格式的私钥和相同的密码:
-
提取公钥,完整的证书链:
OpenSSL pkcs12 -in "MYCERT.pfx" -nokeys -out "MYCERT.cer" -passin "pass:MYPWD"
-
提取私钥:
OpenSSL pkcs12 -in "MYCERT.pfx" -nocerts -out "MYCERT.pem" -passin "pass:MYPWD" -passout "pass:MYPWD"
-
将私钥转换为 RSA 格式:
OpenSSL rsa -inform PEM -in "MYCERT.pem" -out "MYCERT.rsa" -passin "pass:MYPWD" -passout "pass:MYPWD"
-
将公钥与 RSA 私钥合并到新的 PFX:
OpenSSL pkcs12 -export -in "MYCERT.cer" -inkey "MYCERT.rsa" -out "CONVERTED.pfx" -passin "pass:MYPWD" -passout "pass:MYPWD"
如果您加载转换后的 pfx 或将其导入 Windows 证书存储区而不是 CNG 格式的 pfx,问题就会消失,C# 代码不需要更改。
我在自动执行此操作时遇到的另一个问题:我们使用生成的长密码作为私钥,密码可能包含"
。对于 OpenSSL 命令行,密码中的 "
字符必须转义为 ""
。
【讨论】:
这解决了我的问题,希望我能在几个小时前找到它! 我在这里找到了类似的说明:componentspace.com/Forums/ComponentSpace-Knowledge-Bases/… 所以看起来这可能有一些优点。 @Berend,上面的步骤 1 创建了 .cert 文件。 Step2 没有创建 .pem,没有显示错误,但显示“pkcs12:使用 -help 进行摘要”。我做错了什么? @vkelman:OpenSSL 在遇到任何未知参数时都会这样做。我想这取决于版本。我们仍在使用我的工具将 cng 转换为 rsa 证书,使用 OpenSSL 1.0.2d 2015 年 7 月 9 日。如果命令行输出没有让您知道命令行的哪一部分已被弃用,您可能会节省一些时间只需使用存档的 1.0.2d 版本。对于 Windows,可以在此处找到存档版本:indy.fulgan.com/SSL 所以这个答案总结为:“基于旧的 pfx 创建一个新的 pfx”?嗯【参考方案2】:就我而言,我试图通过 PowerShell 的 New-SelfSignedCertificate 命令使用自签名证书。默认情况下,它将使用 CNG (Crypto-Next Generation) API 而不是旧的/经典的加密 CAPI 生成证书。一些较旧的代码会遇到问题;就我而言,它是旧版本的 IdentityServer STS 提供程序。
通过在我的 New-SelfSignedCertificate 命令末尾添加这个,我解决了这个问题:
-KeySpec 密钥交换
powershell命令的开关参考:
https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
【讨论】:
这有帮助,谢谢。我还需要确保用户可以访问私钥,请参阅***.com/questions/12106011/… 爱你!谢谢;) 就是现场,谢谢!事实上,除了None
之外的所有选项都适用于-KeySpec
参数,例如:New-SelfSignedCertificate -DnsName "IssuedToName" -CertStoreLocation "cert:\CurrentUser\My" -KeySpec Signature
谢天谢地,经过这么多小时。对于将来处于我尝试为网站制作本地代理的情况的任何人,您的程序可能需要以管理员身份运行才能访问私钥+证书可能必须在 /Root 而不是 /My 中接受
我们在部署到 Azure 应用服务的应用时遇到了这个问题,这个标志修复了它【参考方案3】:
这是发生这种情况的另一个原因, 这是一个奇怪的问题,经过一天的努力,我解决了这个问题。 作为一项实验,我更改了 "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" 文件夹的权限,该文件夹包含使用机器密钥存储的证书的私钥数据。当您更改此文件夹的权限时,所有私钥都显示为“Microsoft 软件 KSP 提供程序”,它不是提供程序(在我的情况下,它们应该是“Microsoft RSA Schannel 加密提供程序”)。
解决方案:重置 Machinekeys 文件夹的权限
此文件夹的原始权限可以在here 中找到。就我而言,我已经更改了“所有人”的权限,在删除“特殊权限”勾选的地方给予了读取权限。因此,我与我的一位团队成员进行了核对(右键单击文件夹>属性>安全>高级>选择“所有人”>编辑>单击权限复选框列表中的“高级设置”
希望这能拯救别人的一天!
在这里我找到了答案source,感谢他记录了这一点。
【讨论】:
大耳朵干杯。 你是救生员!刚刚在第一次部署到 Amazon EC2 机器时遇到了这个问题,完全困惑为什么我的代码突然开始失败。 这解决了我的问题。不过,我只将完全控制权交给了“IIS AppPool\DefaultAppPool”用户,这是运行我的应用程序的应用程序池所使用的用户帐户。【参考方案4】:在我的例子中,以下代码在 localhost(NET 3.5 和 NET 4.7)中运行良好:
var certificate = new X509Certificate2(certificateBytes, password);
string xml = "....";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml(xml);
SignedXml signedXml = new SignedXml(xmlDocument);
signedXml.SigningKey = certificate.PrivateKey;
//etc...
但在部署到 Azure Web 应用程序时失败,certificate.PrivateKey
修改代码如下:
var certificate = new X509Certificate2(certificateBytes, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
//^ Here
string xml = "....";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml(xml);
SignedXml signedXml = new SignedXml(xmlDocument);
signedXml.SigningKey = certificate.GetRSAPrivateKey();
// ^ Here too
//etc...
感谢 Microsoft Azure,我失去了一整天的工作。
【讨论】:
感谢您的评论。我只浪费了 3 个小时,然后偶然发现了你的评论。它拯救了我的整个周末 GetRSAPrivateKey() 对我来说至关重要 添加X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable
在 Azure 上为我工作
今天它在 localhost 中失败并出现同样的错误,但我通过“以管理员身份”运行 Visual Studio 来修复它
在 Windows Server 2016 下的 IIS 上实现 API 时遇到了同样的问题。第一次修改对我有用。非常感谢。【参考方案5】:
Alejandro's blog 的链接是关键。
我相信这是因为证书是使用 CNG(“下一代加密货币”)API 存储在您的计算机上的。旧的 .NET API 与它不兼容,所以它不起作用。
您可以为此 API 使用 Security.Cryptography 包装器 (available on Codeplex)。这会将扩展方法添加到 X509Certificate/X509Certificate2
,因此您的代码将类似于:
using Security.Cryptography.X509Certificates; // Get extension methods
X509Certificate cert; // Populate from somewhere else...
if (cert.HasCngKey())
var privateKey = cert.GetCngPrivateKey();
else
var privateKey = cert.PrivateKey;
不幸的是,CNG 私钥的对象模型有很大不同。我不确定您是否可以像在原始代码示例中那样将它们导出为 XML...在我的情况下,我只需要使用私钥对一些数据进行签名。
【讨论】:
即使我有 using 子句,我的证书类上也没有 .HasCngKey() 方法。 一定有问题。你能把它明确地称为Security.Cryptography.X509Certificates.X509CertificateExtensionMethods.HasCngKey(cert)
吗?
这仍然是最新的 .NET (4.6) 的方式吗?
@MichaelChan 除了GetCngPrivateKey
已重命名为GetRSAPrivateKey
。我在使用 EncryptedXml 时遇到了这个错误,我发现 net462 中的代码已更新为使用这种新方法,因此不再引发错误。【参考方案6】:
使用 Visual Studio 2019 和 IISExpress,我能够通过在加载 .pfx|.p12
文件时删除以下标志来解决此问题:
X509KeyStorageFlags.MachineKeySet
之前:
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable
之后:
X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable
通常,我会这样加载证书:
var myCert = new X509Certificate2("mykey.pfx", "mypassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
这不会引发异常,而是在尝试使用证书时引发异常(或者在我的情况下,当尝试获取 .PrivateKey
时)。我发现invoking user has insufficient permissions 时可能会导致此问题。
由于我在某些环境中依赖MachineKeySet
标志,因此我当前的解决方案是吞下异常,更改标志,然后重试。 :/
更有机的解决方案是测试权限级别并动态设置此标志,但是我不知道有一种简单的方法可以做到这一点,因此是回退。
注意:我正在使用的 .pfx
文件是从使用 javascript 库 (digitalbazaar/forge
) 的网站创建的,该库不使用 CNG(下一代密码学)密钥存储提供程序。这是导致相同错误的许多常见原因(与CNG
扩展相关的最常见修复,不幸的是,它们甚至更改了.NET 版本中的命名空间),它们会引发相同的错误。在抛出这些类型的错误时,微软最终应该更加冗长。
【讨论】:
【参考方案7】:正如许多其他答案所指出的,当私钥是 Windows 加密:下一代 (CNG) 密钥而不是“经典”Windows 加密 API (CAPI) 密钥时,就会出现此问题。
从 .NET Framework 4.6 开始,可以通过 X509Certificate2 上的扩展方法访问私钥(假设它是 RSA 密钥):cert.GetRSAPrivateKey()
。
当 CNG 持有私钥时,GetRSAPrivateKey
扩展方法将返回一个 RSACng
对象(4.6 中的框架新增)。因为 CNG 具有读取旧 CAPI 软件密钥的传递,GetRSAPrivateKey
通常会返回 RSACng
,即使是 CAPI 密钥;但如果 CNG 无法加载它(例如,它是一个没有 CNG 驱动程序的 HSM 密钥),那么 GetRSAPrivateKey
将返回一个 RSACryptoServiceProvider
。
注意GetRSAPrivateKey
的返回类型是RSA
。从 .NET Framework v4.6 开始,对于标准操作,您不需要强制转换超过 RSA
;使用RSACng
或RSACryptoServiceProvider
的唯一原因是当您需要与使用NCRYPT_KEY_HANDLE
或密钥标识符(或按名称打开持久密钥)的程序或库进行互操作时。 (.NET Framework v4.6 有很多地方仍然将输入对象强制转换为RSACryptoServiceProvider
,但是这些都被 4.6.2 淘汰了(当然,这已经是 2 多年前的事了)。
ECDSA 证书支持在 4.6.1 中通过GetECDsaPrivateKey
扩展方法添加,DSA 在 4.6.2 中通过GetDSAPrivateKey
升级。
在 .NET Core 上,Get[Algorithm]PrivateKey
的返回值会根据操作系统而变化。对于 RSA,它在 Windows 上是 RSACng
/RSACryptoServiceProvider
,在 Linux(或除 macOS 之外的任何类 UNIX 操作系统)上是 RSAOpenSsl
,在 macOS 上是非公共类型(这意味着您不能将其投射到 RSA
之外) .
【讨论】:
【参考方案8】:什么对我有用: IIS / 应用程序池 / 加载用户配置文件 = true
【讨论】:
【参考方案9】:我也遇到了这个问题,在尝试了这篇文章中的建议后没有成功。我能够通过使用 Digicert 证书实用程序 https://www.digicert.com/util/ 重新加载证书来解决我的问题。这允许人们选择将证书加载到的提供程序。在我的情况下,将证书加载到 Microsoft RSA Schannel Cryptographic Provider 提供程序中,我原本预计它会首先解决这个问题。
【讨论】:
【参考方案10】:来自@berend-engelbrecht 的答案的Powershell 版本,假设openssl
通过chocolatey 安装
function Fix-Certificates($certPasswordPlain)
$certs = Get-ChildItem -path "*.pfx" -Exclude "*.converted.pfx"
$certs | ForEach-Object
$certFile = $_
$shortName = [io.path]::GetFileNameWithoutExtension($certFile.Name)
Write-Host "Importing $shortName"
$finalPfx = "$shortName.converted.pfx"
Set-Alias openssl "C:\Program Files\OpenSSL\bin\openssl.exe"
# Extract public key
OpenSSL pkcs12 -in $certFile.Fullname -nokeys -out "$shortName.cer" -passin "pass:$certPasswordPlain"
# Extract private key
OpenSSL pkcs12 -in $certFile.Fullname -nocerts -out "$shortName.pem" -passin "pass:$certPasswordPlain" -passout "pass:$certPasswordPlain"
# Convert private key to RSA format
OpenSSL rsa -inform PEM -in "$shortName.pem" -out "$shortName.rsa" -passin "pass:$certPasswordPlain" -passout "pass:$certPasswordPlain" 2>$null
# Merge public keys with RSA private key to new PFX
OpenSSL pkcs12 -export -in "$shortName.cer" -inkey "$shortName.rsa" -out $finalPfx -passin "pass:$certPasswordPlain" -passout "pass:$certPasswordPlain"
# Clean up
Remove-Item "$shortName.pem"
Remove-Item "$shortName.cer"
Remove-Item "$shortName.rsa"
Write-Host "$finalPfx created"
# Execute in cert folder
Fix-Certificates password
【讨论】:
【参考方案11】:我在我们的 IIS 应用程序中遇到了同样的问题:
System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer, Boolean silent)
System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer, Boolean silent)
System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
这里提到的重新生成证书没有帮助。 我还注意到测试控制台应用程序在池用户下运行良好。
清除 IIS 应用程序池的“启用 32 位应用程序”设置后问题消失。
【讨论】:
【参考方案12】:对于 .net 4.8 WCF 服务,我收到此错误,因为我没有(也)设置 httpRuntime 版本。
如果没有设置 httpRuntime,只要存在安全的 .net tcp 绑定,我就会收到错误消息。
<system.web>
<compilation targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
<!--<customErrors mode="Off" />-->
</system.web>
我已经在 mmc.exe 中设置了所需的权限 -> 添加管理单元 -> 证书 -> 个人 -> 所有任务 -> 管理私钥 -> 添加 [计算机名称]\IIS_IUSRS(我所有的应用程序池都是ApplicationPoolIdentity [默认] - 由 IIS_IUSRS 覆盖)
【讨论】:
对我来说也一样; net472 用于 WCF 服务;添加 httpRuntime 472 或 48 解决了这个问题。但奇怪的是,我无法在此证书上使用 findprivatekey 工具,如果我尝试以管理员身份更改 pk 文件的权限,我在枚举上遇到错误,并且对一个文件没有读取权限!【参考方案13】:PrivateKey 和 PublicKey 属性已过时,从 NET 4.6 开始。请使用:
cert.GetRSAPrivateKey() 或 GetECDsaPrivateKey() cert.GetRSAPublicKey() 或 GetECDsaPublicKey()问候
【讨论】:
【参考方案14】:遵循接受的答案(指定 KeySpec)后,异常更改为 System.Security.Cryptography.CryptographicException: Invalid provider type specified.
。我通过让我的 Web 应用程序访问私钥 (IIS_IUSRS) 解决了该异常。我发现这也可以解决我原始证书的问题。因此,在生成和部署新证书之前,还要检查私钥的权限。
【讨论】:
【参考方案15】:问题是您的代码无法读取 PFX 文件。 通过执行以下步骤将 pfx 文件转换为 RSA 格式。
获取证书并从证书中提取 pfx 文件。
使用下面的密码 123456 快速解决问题。
将您的 pfx 重命名为“my.pfx”文件以使其简单,并将其放入“C:\Certi” 确保您已经在系统中安装了 Open SSL。 在 windows 系统中打开 cmd 并输入 --> OpenSSL 保持冷静,一个接一个地运行这些——> 复制粘贴。 *注意
-passin 是您的 Pfx 文件密码 -passout是转换后的pfx的新密码。
1. pkcs12 -in "C:\Certi\my.pfx" -nokeys -out "C:\Certi\MYCERT.cer" -passin "pass:123456"
2. pkcs12 -in "C:\Certi\my.pfx" -nocerts –out “C:\Certi\MYCERT.pem" -passin "pass:123456" -passout "pass:123456"
3. rsa -inform PEM -in "C:\Certi\MYCERT.pem" -out "C:\Certi\MYCERT.rsa" -passin "pass:123456" -passout "pass:123456"
如果您在第三条命令中遇到问题,请转到此处https://decoder.link/converter 单击 PKC#12 到 PEM 上传您的 pfx 文件并在线转换。 下载压缩文件。 它包含 3 个文件。只需复制“.key”文件并将其重命名为 my.key 并放入“C:\Certi”
4. rsa -in C:\Certi\my.key -out C:\Certi\domain-rsa.key
5. pkcs12 -export -in "C:\Certi\MYCERT.cer" -inkey "C:\Certi\domain-rsa.key" -out "C:\Certi\CONVERTED.pfx" -passin "pass:123456" -passout "pass:123456"
**Also, you can try below things if the issue still persists**
授予对应用程序池或 IIS 用户对文件夹“强制执行”的访问权限
路径 ---> C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
删除旧密钥(收拾残局) 路径---> C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys【讨论】:
【参考方案16】:在我从商店中删除证书并使用证书导入向导(双击 .pfx 文件)和额外的导入选项从 .pfx 文件中再次导入后,此错误消失了。
检查导入选项后(与输入密码相同的步骤):
“将此密钥标记为可导出。这将允许您稍后备份或传输您的密钥。”
现在可以从代码中访问私钥而不会出现任何错误。
我还在第 2 步到最后一步明确选择了“个人”商店,但我认为这并不重要。
【讨论】:
【参考方案17】:我尝试了这篇文章中的所有内容,但对我来说解决方案是:
-
将原始 .p12 文件导入我的本地机器
将其导出为 .pfx 文件,检查“导出所有扩展属性”和“如果可能,将所有证书包括在证书路径中”选项
使用此post 解决方案中的此标志选项读取新证书:
var certificate = new X509Certificate2(certKeyFilePath, passCode,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet );
【讨论】:
【参考方案18】:似乎在 Windows 10 上,如果我在没有管理权限的情况下运行我的程序(无论我使用 PrivateKey 属性还是 GetRSAPrivateKey() 扩展方法),我都会看到此异常(有关异常,请参阅此讨论线程的标题) .如果我以管理权限运行我的程序并使用 PrivateKey 属性,我也会看到这个异常。只有当我以管理权限运行我的程序并使用 GetRSAPrivateKey() 扩展方法时,我才不会看到此异常。
【讨论】:
【参考方案19】:我也遇到了这个问题,我在没有输入密码的情况下将“.jks”更改为“.pfx”,一旦我再次使用密码更改了密钥库类型,它就成功了。
【讨论】:
【参考方案20】:在安全关键环境中的某些计算机上遇到此问题后,我发现与几个答案相反,将证书的 Cryptographic Service Provider (CSP) 从旧 CAPI 标准更新为新 CNG 标准解决了此问题.
安全策略可能限制了依赖于deprecated cryptographic algorithms 的 CSP 的使用。
基于these instructions 将 CSP 更新为 Microsoft Software Key Storage Provider 解决了这些问题。
【讨论】:
以上是关于尝试加载证书的私钥时出现“指定的提供程序类型无效”CryptographicException的主要内容,如果未能解决你的问题,请参考以下文章
收到“警告:未受保护的私钥文件!”尝试导入 SSH 密钥时出现错误消息 [关闭]
WCF 错误:“证书“我的证书”可能没有能够进行密钥交换的私钥
Azure 无法访问证书 PrivateKey“指定的提供程序类型无效”