我有一个 WinForms 应用程序,它使用 WCF,并将证书作为参数传递给函数:
mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...
在 WCF 服务中,我从字节数组中重新创建了证书:
public void SendDocument (byte[] binaryCert)
{
X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...
但是当使用证书签署xml时,出现错误“Keyset不存在”:
if (cert.HasPrivateKey) // WORKS!!!
{
signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...
在我的电脑上,该应用程序运行 100%!但是在WebServer中,我得到了这个错误!
问题是:即使从字节数组重新创建 X509Certificate2,我也需要一些特殊权限才能访问私钥?
谢谢!
如果您使用的是Windows Server 2008或Windows 7,那么您需要读取私钥的权限。
FindPrivateKey 我的本地机器 -n "CN=MyCert" –a
它返回路径:C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys[文件名]
转到该路径并打开文件属性
转到安全选项卡
点击“编辑”,然后点击“添加”
在打开的对话框中写入:IIS AppPool\[您的应用程序池名称],然后单击“确定”
现在您的应用程序池有权限读取此私钥。
我遇到了这个问题,我的证书有私钥,但我收到此错误(“密钥集不存在”)
原因: 您的网站在“网络服务”帐户下运行或权限较低。
解决方案:将应用程序池标识更改为“本地系统”,重置IIS并再次检查。如果它开始工作,这是权限/较少权限问题,您也可以冒充然后使用其他帐户。
我面临着同样的问题,我不知道如何(为我感到羞耻),但它有效:
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
希望有人能解答这个谜团。
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 in
然后继续 Vano Maisuradze 的回答
对于本地开发,请确保用户有权访问证书,特别是当您将其安装在本地计算机存储中时。
我使用 Rider 调试它时就是这种情况。
我认为问题在于您需要将密钥添加到机器的证书存储中。
默认情况下,应用程序池身份帐户无权访问证书存储。
您可以按照 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
安装证书时还需要启用
Mark this key as exportable
选项。
几个故障排除步骤:
如果您能够调试应用程序,请尝试在管理模式下运行 IDE。您还可以从 MMC 添加新用户。
我在 c# 控制台应用程序上遇到了同样的问题,在阅读此处的答案后,我认为问题出在权限上。然后我以管理员身份运行 visual studio 并且它起作用了。
由于私钥属于敏感信息,因此它们不与证书存储在同一位置。 与 Vano Maisuradze 的方法类似,您可以使用 Process Monitor 实用程序 捕获系统服务的跟踪并识别文件在文件系统上的位置。然后授予用户对该文件的读取权限,“密钥集不存在”错误应该得到解决。您还可以在 procman 中找到正在运行该线程的用户。