X509Certificate - 密钥集不存在

Bru*_*oXP 31 c# wcf x509certificate

我有一个使用WCF 的WinForms应用程序,并作为参数传递给函数证书:

mySvcClient.SendDocument(cert.Export(X509ContentType.SerializedCert, "password"));
...
Run Code Online (Sandbox Code Playgroud)

在WCF服务中,我从字节数组重新创建了证书:

public void SendDocument (byte[] binaryCert)
{   
     X509Certificate2 cert = new X509Certificate2(binaryCert, "password");
...
Run Code Online (Sandbox Code Playgroud)

但是当使用证书签署xml时,我收到错误"Keyset不存在":

if (cert.HasPrivateKey) // WORKS!!!
{   
    signedXml.SigningKey = cert.PrivateKey; // THROW "keyset does not exist" EXCEPTION
...
Run Code Online (Sandbox Code Playgroud)

在我的电脑中,该应用程序100%工作!但是在WebServer中,我收到了这个错误!

问题是:即使X509Certificate2从一个字节数组重新创建,我需要一些特殊权限才能访问私钥?

谢谢!

Van*_*dze 35

如果您使用的是Windows Server 2008或Windows 7,则需要具有读取私钥的权限.

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

FindPrivateKey My LocalMachine -n​​"CN = MyCert"-a

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

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

  2. 转到安全选项卡

  3. 点击"编辑"然后"添加"

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

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

  • 设置证书权限的另一种方法是通过证书SnapIn,如下所述:http://stackoverflow.com/a/3176253/844207 (4认同)

Vai*_*red 32

我遇到过这个问题,我的证书有私钥,但是我收到了这个错误(" Keyset不存在 ")

原因:您的网站在" 网络服务 "帐户下运行或具有较少的权限.

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


Kim*_*jan 12

我面临着同样的问题,我不知道(对我来说是多么羞耻),但它有效:

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
Run Code Online (Sandbox Code Playgroud)

我希望有人能回答这个谜.

  • @Everyone请注意,此解决方案适用于.Net 4.6或更高版本,根据其上的MSDN页面. (3认同)
  • 此解决方案也适用于基于 .NET 6 的 WPF 应用程序。就我而言,我不需要做黑魔法部分。只需将 X509KeyStorageFlags.PersistKeySet 添加到密钥存储标志对我有用。X509证书2?证书 = new X509Certificate2(certificateFilePath, 密码, X509KeyStorageFlags.PersistKeySet);。我感谢 Nisarg Shah 和 @Kim Tranjan 对此事的帮助。 (2认同)

小智 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\bin

然后继续Vano Maisuradze的回答


Xin*_*nt0 2

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