WCF,证书身份验证 - 常见错误和令人困惑的参数

时间:2011-03-15 19:05:36

标签: x509certificate certificate makecert certificate-store wcf-authentication

我正在尝试设置WCF服务以使用证书来验证客户端。我已经阅读了很多关于如何创建证书的帖子,我已经能够这样做了(最后)。

我正在运行Windows 2008 R2的服务器上安装证书颁发机构和证书。当我打开MMC证书管理单元时,我选择计算机帐户。它是否正确?我这样做是因为我的WCF服务将在Windows服务中运行,即使没有用户登录也会运行。但不可否认,我不知道这三个选项之间有什么区别:

  1. 我的用户帐户
  2. 服务帐户
  3. 计算机帐户
  4. 管理单元加载后,我将Authority Cert导入受信任的根证书颁发机构。然后,我将证书导入受信任的发布者。这样做时我没有遇到任何错误。当我执行权威证书和该权限签署的证书时,我不会对.pvk文件进行任何引用。我的理解是私钥嵌入在证书或授权证书中。以下是我用来创建每个证书的命令:

    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
    

    注意我使用了-ss root。我见过很多帖子使用-ss My。我真的不明白差异是什么,或者什么时候适合使用每个值。

    我的WCF服务在托管服务(Windows服务)内的此计算机上运行。当我启动托管WCF服务的Windows服务时,它会立即崩溃,并在事件查看器中报告一个看似常见的错误:

      

    System.ArgumentException:很可能   证书'CN = TempCertName'可以   没有能够使用的私钥   密钥交换或过程可能不会   拥有私钥的访问权限

    我发现帖子说我需要向运行服务的用户授予对密钥的权限。

    这个似乎是stackoverflow上的热门答案:Grant access with All Tasks/Manage Private Keys

    但我没有所有任务/管理私人密钥

    的选项

    但我不清楚如何做到这一点。此外,该服务在我的域帐户下运行,该帐户是管理员,也是安装证书的用户。

    请帮助:)

2 个答案:

答案 0 :(得分:1)

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

从上面的指南开始工作后,您可能希望在安装期间设置服务programatically to use the right certificate

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

接下来,如果您仍然遇到错误,可以使用WCF Tracing进一步调试。此外,您还应该启用WCF Message Tracing。如果WCF跟踪没有提供足够的信息,您也可以trace the .NET network stack

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

答案 1 :(得分:1)

我认为你很亲密。以下是一些建议:

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

  2. 我会使用-ss my并将证书(带私钥)放入个人存储区。 Here我明白这一点:

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

  3. 所以无论你指向同等的地方,都要把证书放在那里。

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

      < / LI>
    2. 您不需要在服务器计算机上本地使用CA证书,因为只有客户端才需要它。但它没有受到伤害,如果服务器上的任何东西连接到本地服务,则需要它。此外,它使得InternalWebService证书在MMC管理单元上看起来很好。您可以在受信任的根存储中尝试使用和不使用CA,您将看到我的意思。但无论如何,我将CA的私钥放入本地计算机商店。

    3. 从MMC管理单元检查InternalWebService的私钥权限(右键单击证书,然后单击任务,管理私钥...)如果在不同的用户帐户下导入,则运行的服务不同于,当然它还没有访问权限,你必须去访问它。否则服务将获得证书,但证明证书没有私钥。

    4. 总结:

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

      • 将InternalWebService放在Web服务正在查找的位置。我猜“个人”(a.k.a。“我的”),但你知道你的服务配置在哪里。无论是当前用户还是本地计算机,请查看您的配置。

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

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