【问题标题】:The certificate 'CN=ds.com' must have a private key. The process must have access rights for the private key证书“CN=ds.com”必须具有私钥。该进程必须具有私钥的访问权限
【发布时间】:2018-12-12 23:17:07
【问题描述】:

在搜索了很多并尝试了其他人的答案之后,每个解决方案 - 仍然没有成功

简短的前言:从我的机器到自身的响应请求 - 确实适用于证书。从另一台计算机到我的机器 - 它没有。

在我的机器中-我创建了 2 个证书:公钥和私钥通过:

makecert -r -pe -n "CN=ds.com" -b 01/01/2018 -e 01/01/2020 
-sky exchange Server.cer -sv Server.pvk

然后:

pvk2pfx.exe -pvk Server.pvk -spc Server.cer -pfx Server.pfx

(取自here

我已经将它们 both 安装在我机器的商店中(通过 mmc):

我正在使用这个简单的WCF config,它托管在我的机器上的WAS IIS中。

当我用这个简单的代码调用该服务(从我的机器到它自己)时:

  WSHttpBinding myBinding = new WSHttpBinding();
            myBinding.Security.Mode = SecurityMode.Message;
            myBinding.Security.Message.ClientCredentialType =MessageCredentialType.Certificate;
            EndpointAddress ea = new
                EndpointAddress("http://ds.com/Service1.svc/HelloWorldService");

            var client   = new HelloWorldServiceClient(myBinding, ea);

            client.ClientCredentials.ClientCertificate.SetCertificate(
                StoreLocation.CurrentUser,
                StoreName.Root,
                X509FindType.FindByThumbprint,
                "9394f570069e7af263ef7ca5a46a5bcab9f68659");
    Console.WriteLine(client.GetMessage("Mike Liu"));
    Console.ReadLine();
    client.Close();

—我确实得到了结果:

太棒了。

现在让我们转到另一台计算机,我已在将公钥证书安装到受信任的根目录中。

但是 - 现在当我访问 我的 计算机(使用相同的代码 ^)时 - 我收到以下错误:

证书“CN=ds.com”必须具有私钥。该过程必须 拥有私钥的访问权限。

即使我关闭了我计算机上的 WAS IIS 服务,我仍然会在另一台计算机上看到错误。

看来问题只出在另一台机器上。我已经在另一台机器上设置了权限:

C:\ProgramData\Microsoft\Crypto <--------Everyone: full control +inheritance

问题:

我在这里缺少什么?为什么它在客户端机器中寻找私钥。它不应该有私钥。专用计算机应仅驻留在服务计算机中。 (这是我的机器)。

Full stack trace image (at the other machine)

【问题讨论】:

    标签: c# wcf iis certificate makecert


    【解决方案1】:

    在您的示例中,您在服务器和客户端上使用相同的证书。这不是应该的。

    为了确保客户端请求的安全,您必须使用客户端证书对请求进行签名,并且使用服务器证书对服务器响应进行签名。

    所以在客户端你应该有:

    • 其个人证书存储中的客户端证书的私有(和公共)密钥
    • 受信任的根权限内的服务器证书的公钥

    在服务器上你应该有相反的:

    • 服务器证书在其个人证书存储中的私钥(和公钥)
    • 受信任的根权限内的客户端证书公钥

    您可以查看示例 here 并阅读有关它的更多信息 here

    article 很好地描述了有关 HTTPS 协议的详细信息。

    【讨论】:

    • 感谢您的回复 - 据我了解(可能是错误的),服务器应该有公共和私人证书。而用户应该只有 public。他们可以加密只有私钥才能打开的数据。不 ?如果是这样 - 我不明白为什么世界各地的客户都应该拥有私钥。
    • 在客户端和服务器之间的通信中,您有请求和响应。来自客户端的请求使用服务器公钥加密,并使用服务器上的服务器私钥解密。来自服务器的响应使用客户端公钥加密,并在客户端使用客户端私钥解密。所以是的,你两者都需要。
    • 嗨。您说“有关 HTTPS 的详细信息” - 但我的代码使用 EndpointAddress ea = new EndpointAddress("http://ds.com/Service1.svc/HelloWorldService");(不是 HTTPS)。那么它是如何工作的呢?另外 - `client.ClientCredentials.ClientCertificate.SetCertificate` 代码是用于加密消息还是用于解密 - 当响应从服务器返回时?
    • 我并没有真正注意这一点。您正在使用SecurityMode.Message。这意味着消息是加密的,而不是传输层 (HTTPS)。关于公钥/私钥和加密的理论仍然是相同的。您可以在this question 中查看 WCF 安全模式的差异。
    【解决方案2】:

    这可能是由于 2 个可能的原因。

    1. 证书当前用户存储(个人/受信任的人)中没有可用的私钥
    2. IIS 应用程序池无权访问(当前用户存储)的私钥

    启用 wcf 跟踪,您将在图像中提到的日志中发现错误。

    对于 1) 安装私钥 (pfx) 第二个在应用程序池中提供身份,如下图所示。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      相关资源
      最近更新 更多