2

I am trying to setup a WCF service to use a Certificate for Authenticating the client. I have read tons of posts on how to create the certificate, and I have been able to do so (finally).

I am installing the Cert Authority and the Cert on a server that runs Windows 2008 R2. When I open the MMC Certificates Snap-in, I choose Computer Account. Is this correct? I am doing this because my WCF service will run in a Windows Service, and will be running even when no user's are logged in. But admittedly, I don't know what the difference is between the three options:

  1. My user account
  2. Service account
  3. Computer account

Once the snap-in loads, I import the Authority Cert into Trusted Root Certification Authorities. Then, I import the cert into Trusted Publishers. I don't encounter any errors when doing this. When I do the import, of both the Authority Cert and the Cert signed by that authority, I don't make any reference to the .pvk file. It is my understanding that the private key is embedded in either the cert or the authority cert. Here are the commands I use to create each cert:

MakeCert.exe
  -n “CN=InternalCA”
  -r
  -sv InternalCA.pvk InternalCA.cer
  -cy authority


MakeCert.exe
  -sk InternalWebService
  -iv InternalCA.pvk
  -n “CN=InternalWebService”
  -ic InternalCA.cer InternalWebService.cer
  -sr localmachine
  -ss root
  -sky exchange
  -pe

Notice I used -ss root. I have seen many posts using -ss My. I don't really understand what the difference is or when it is appropriate to use each value.

My WCF service runs on this machine inside a Managed Service (Windows Service). When I start my windows service, which hosts the WCF service, it crashes immediately and a seemingly common error is reported in the event viewer:

System.ArgumentException: It is likely that certificate 'CN=TempCertName' may not have a private key that is capable of key exchange or the process may not have access rights for the private key

I have found posts that say I need to grant permissions to the user running the service to the key.

This one seems to be a popular answer here on stackoverflow: Grant access with All Tasks/Manage Private Keys

But I don't have the option of All Tasks/Manage Private Keys

But I'm not clear on how to do that. But also, the service is running under my domain account, which is an administrator and is also the same user that installed the cert.

Please Help :)

4

2 回答 2

1

我认为你很接近。以下是一些建议:

  1. 确保在第二步中获得附加到证书的私钥。您必须在提升的进程中运行该命令——即使您具有管理员权限,您也必须,例如,右键单击并“以管理员身份运行”来启动您用于此命令的命令外壳。否则,您将无法将私钥放入 localMachine 存储中。

  2. 我会使用-ss my证书(带有私钥)并将其放入个人存储中。在这里,我看到了:

    cc.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser,StoreName.My,X509FindType.FindBySubjectName,“contoso.com”);

因此,无论您在等效项中指向何处,都将证书放在那里。

  1. 您不需要导入 CA 证书的私钥(您创建的第一个证书)。这只是为了使用 MakeCert 签署更多证书。您需要在正在连接的客户端上获得该 CA 证书的副本(没有私钥!),否则客户端将无法验证 InternalWebService 证书。

  2. 您实际上并不需要服务器机器上本地的 CA 证书,因为它只会被客户端需要。但这并没有什么坏处,如果服务器上的任何东西在本地连接到服务,它就会被需要。此外,它使 InternalWebService 证书在 MMC 管理单元上看起来不错。您可以在受信任的根存储中尝试使用和不使用 CA,您会明白我的意思。但无论如何,我不会将 CA 的私钥放入本地计算机存储中。

  3. 从 MMC 管理单元检查 InternalWebService 的私钥权限(右键单击证书,然后单击任务、管理私钥...)还没有访问权限,你必须去给它访问权限。否则服务会获取证书,但会显示证书没有私钥。

总结一下:

  • 以管理员权限运行以确保 InternalWebService 的私钥真正进入证书存储区。(您将在 MMC 管理单元中的证书上看到一个小密钥,右键单击证书将有一个选项“管理私钥...”,如果没有附加私钥,则该选项不存在。)

  • 将 InternalWebService 放在您的 Web 服务正在寻找它的位置。我猜是“个人”(又名“我的”),但您知道它在您的服务配置中的位置。无论是当前用户还是本地机器,请查看您的配置。

  • 授予对 InternalWebService 证书私钥的访问权限。

  • 将 CA 证书(没有其私钥)放在受信任的根目录下,您还需要将其放在客户端上(或者让客户端在其末尾接受“不受信任的证书”。)

于 2011-04-09T03:37:22.877 回答
1

这是可以帮助您让自托管 SSL WCF 服务与您自己的自定义 CA/证书一起使用的最佳链接:SSL with Self-hosted WCF Service

从上面的指南中得到它之后,您可能希望以编程方式设置您的服务,以便在安装时使用正确的证书

我发现使用HTTPCfgUIhttpcfg工具验证我的 HTTP.SYS 配置比通过命令行/命令更容易netsh

接下来,如果您仍然遇到错误,您可以使用WCF Tracing进一步调试。此外,您还应该打开WCF 消息跟踪。如果 WCF 跟踪没有提供足够的信息,您也可以跟踪 .NET 网络堆栈。

您可以通过在另一台机器上的浏览器中点击您的服务 URL 来测试您在服务上的证书/CA 对是否正常工作。它应该首先声明证书无效。然后,将机器上的 CA 导入受信任的根目录,然后再次点击服务 URL。这次它应该像往常一样显示服务描述页面,没有警告。

于 2011-03-16T18:05:42.867 回答