X509Certificate - 密钥集不存在
Posted
技术标签:
【中文标题】X509Certificate - 密钥集不存在【英文标题】:X509Certificate - Keyset does not exist 【发布时间】:2011-09-17 13:09:35 【问题描述】:我有一个使用 WCF 的 WinForms 应用程序,并将证书作为参数传递给函数:
mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...
在 WCF 服务中,我从字节数组重新创建了证书:
public void SendDocument (byte[] binaryCert)
X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...
但是当使用证书对xml进行签名时,出现错误“Keyset does not exist”:
if (cert.HasPrivateKey) // WORKS!!!
signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...
在我的电脑中,应用程序 100% 运行!但是在 WebServer 中,我得到了这个错误!
问题是:即使 X509Certificate2 是从字节数组重新创建的,我需要一些特殊权限才能访问私钥吗?
谢谢!
【问题讨论】:
该链接可能对您有所帮助...***.com/a/39223239/3857542 我遇到了同样的问题,这是唯一对我有用的解决方案***.com/a/57667772/591656 【参考方案1】:如果您使用的是windows server 2008或windows 7,那么您需要读取私钥的权限。
-
使用 FindPrivateKey 工具查找路径。
例如:
FindPrivateKey My LocalMachine -n "CN=MyCert" –a
它返回路径:C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys[文件名]
转到该路径并打开文件属性
转到安全选项卡
点击“编辑”,然后点击“添加”
在打开的对话框中写入:IIS AppPool\[您的应用程序池名称],然后单击确定
现在您的应用程序池有权读取此私钥。
【讨论】:
另一种设置证书权限的方法是通过证书管理单元,此处描述:***.com/a/3176253/844207【参考方案2】:我遇到了这个问题,我的证书有私钥但我收到了这个错误(“密钥集不存在”)
原因:您的网站在“网络服务”帐户下运行或权限较低。
解决方案:将应用程序池标识更改为“本地系统”,重置 IIS 并再次检查。如果它开始工作,那就是权限/较少权限问题,您也可以模拟然后使用其他帐户。
【讨论】:
似乎还有一种情况,即使您的应用程序池标识是具有正确权限的帐户,您仍然需要授予 IIS_IUSRS 组具有读取权限才能完成操作,如果您尝试访问应用程序的 Application_Start 中的私钥。 就我而言,我必须将应用程序池标识更改为Local System
并提供对 IIS_IUSRS
的私钥访问权限。证书需要安装在本地计算机商店。
这是开发环境和部署的一种更简单的方法。
不要在生产环境中使用本地系统权限,不建议这样做,因为您对应用程序池的权限超过管理员权限。很危险。【参考方案3】:
我也遇到了同样的问题,但我不知道怎么做(真为我感到羞耻),但它奏效了:
var certificate = new X509Certificate2(filePath, password,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
certificate.PrivateKey; // before: error "KeySet does not exist"!
using (certificate.GetRSAPrivateKey()) // pure black magic
certificate.PrivateKey; // after: just works! lol
希望有人能解答这个谜题。
【讨论】:
@Everyone 请注意,根据 MSDN 页面,此解决方案适用于 .Net 4.6 或更高版本。 这解决了我的问题。PrivateKey
在我的本地机器上工作,但在部署的代码上没有工作。
不起作用。仍然随机抛出“Keyset不存在”【参考方案4】:
Vano Maisuradze 回答有效。如果您正在寻找 FindPrivateKey 工具,它包含在适用于 .NET Framework 4 的 Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 示例中,可在此处找到:http://www.microsoft.com/en-us/download/confirmation.aspx?id=21459
下载并解压后,在 Visual Studio 中打开项目:WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS 并进行编译。然后打开命令提示符并导航到:WF_WCF_Samples\WCF\Setup\FindPrivateKey\CS\bin
然后继续 Vano Maisuradze 的回答
【讨论】:
【参考方案5】:我认为问题在于您需要将密钥添加到机器的证书存储中。
【讨论】:
【参考方案6】:默认情况下,应用程序池身份帐户无权访问证书存储。
您要么更改为 Vaibhav.Inspired 指出的 Network Services
帐户,要么授予对证书的访问权限。
要允许访问,请执行以下命令:
WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "IssuedToName" -a “帐户名”
注意事项:
- The tool may need to be installed first. The setup will place the tool at `C:\Program Files (x86)\Windows Resource Kits\Tools\WinHttpCertCfg.exe`.
- `IssuedName` is the issuer property of the certificate that the application will attempt to access
- The command must be run from command prompt with elevated privileges
参考:https://support.microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica第二步
您还需要在安装证书时启用Mark this key as exportable
选项。
【讨论】:
【参考方案7】:几个故障排除步骤:
-
以管理员身份运行程序
如果是部署在 IIS 中的 Web 应用程序 -> 则将 IIS_IUSRS 添加到证书权限。在 Personal 中选择证书,右键单击-> Manage Private Keys -> 添加用户。
如果处于调试状态,则在管理员模式下运行 Visual Studio 以解决此问题
【讨论】:
以上是关于X509Certificate - 密钥集不存在的主要内容,如果未能解决你的问题,请参考以下文章
System.Security.Cryptography.CryptographicException:密钥集不存在
从 x509Certificate2 启动 RSACryptoServiceProvider 的最佳方式?
RSAParameters 到 pfx (X509Certificate2) 的转换