X509证书 - 密钥集不存在

问题描述 投票:0回答:11

我有一个 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,我也需要一些特殊权限才能访问私钥?

谢谢!

c# wcf x509certificate
11个回答
47
投票

如果您使用的是Windows Server 2008或Windows 7,那么您需要读取私钥的权限。

  1. 使用FindPrivateKey工具查找路径。 例如:

FindPrivateKey 我的本地机器 -n "CN=MyCert" –a

它返回路径:C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys[文件名]

  1. 转到该路径并打开文件属性

  2. 转到安全选项卡

  3. 点击“编辑”,然后点击“添加”

  4. 在打开的对话框中写入:IIS AppPool\[您的应用程序池名称],然后单击“确定”

现在您的应用程序池有权限读取此私钥。


41
投票

我遇到了这个问题,我的证书有私钥,但我收到此错误(“密钥集不存在”)

原因: 您的网站在“网络服务”帐户下运行或权限较低。

解决方案:将应用程序池标识更改为“本地系统”,重置IIS并再次检查。如果它开始工作,这是权限/较少权限问题,您也可以冒充然后使用其他帐户。


22
投票

我面临着同样的问题,我不知道如何(为我感到羞耻),但它有效:

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

希望有人能解答这个谜团。


5
投票

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 的回答


3
投票

对于本地开发,请确保用户有权访问证书,特别是当您将其安装在本地计算机存储中时。

  1. 打开证书管理器(mmc.exe 或 certlm)
  2. 前往证书
  3. 右键单击>所有任务>管理私钥
  4. 为当前用户分配权限
  5. 完成

我使用 Rider 调试它时就是这种情况。


2
投票

我认为问题在于您需要将密钥添加到机器的证书存储中。


0
投票

默认情况下,应用程序池身份帐户无权访问证书存储。

您可以按照 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 步骤 2

安装证书时还需要启用

Mark this key as exportable
选项。


0
投票

几个故障排除步骤:

  1. 以管理员身份运行程序
  2. 如果是部署在IIS中的Web应用程序->则将IIS_IUSRS添加到证书权限中。在个人中选择证书,右键->管理私钥->添加用户。
  3. 如果处于调试模式,请在管理模式下运行 Visual Studio 来解决此问题

0
投票

如果您能够调试应用程序,请尝试在管理模式下运行 IDE。您还可以从 MMC 添加新用户。


0
投票

我在 c# 控制台应用程序上遇到了同样的问题,在阅读此处的答案后,我认为问题出在权限上。然后我以管理员身份运行 visual studio 并且它起作用了。


0
投票

由于私钥属于敏感信息,因此它们不与证书存储在同一位置。 与 Vano Maisuradze 的方法类似,您可以使用 Process Monitor 实用程序 捕获系统服务的跟踪并识别文件在文件系统上的位置。然后授予用户对该文件的读取权限,“密钥集不存在”错误应该得到解决。您还可以在 procman 中找到正在运行该线程的用户。

© www.soinside.com 2019 - 2024. All rights reserved.