4

我有一个黑盒服务,我必须使用返回 xml 的简单休息命令来调用它。

他们向我们颁发了一个证书,该证书必须在 IE 中运行并安装到 IE 的证书部分。根据他们的指示,我将它与整个链一起导出为带有密码的 pfx。

在证书直接颁发到的机器上,代码中一切正常

        var certHandler = new WebRequestHandler();
        certHandler.ClientCertificateOptions = ClientCertificateOption.Manual;            
        certHandler.UseDefaultCredentials = false;

        var certificate = new X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); //Must be renewed and replaced every year.
        certHandler.ClientCertificates.Add(certificate);            

        //Execute the command            
        var client = new HttpClient(certHandler);
        string result;
        try
        {
            result = await client.GetStringAsync(url);

            System.Diagnostics.Debug.WriteLine(result);
        }
        catch (Exception ex)
        {
            throw ex;
        }

(我已将证书存储在资源中,但它可以正常加载,并且从文件加载它在开发人员机器上也可以正常工作。)我还将它导入服务器上的 IE 以防万一。显然,这可能是在错误的证书存储下,但我无法弄清楚如何在全局范围内加载它。我可以告诉你,相同的 REST GET 在服务器上的 IE 中工作,就像在开发人员机器上一样。它只是在代码中失败。)

在生产中,同样的代码会抛出 403 禁止。

生产(实际上是一个测试版服务器)实际上与开发机器位于相同的 nat 后面,因此他们看到相同的 IP 通过等。

任何想法为什么它会在服务器上而不是在开发人员框中失败?

谢谢!

4

2 回答 2

4

您应该X509KeyStorageFlags根据您的应用程序运行的帐户使用。如果是

1) 在您应该使用的常规 Windows 用户帐户下运行的应用程序

X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.UserKeySet);

2)LocalSystem下的Windows Service,NetworkService下的IIS或内置Windows Account下的其他服务,你应该使用

X509Certificate2(Properties.Resources.SigningCert, "password", X509KeyStorageFlags.MachineKeySet);

基本上,您不应该X509KeyStorageFlags.PersistKeySet在您的情况下使用 - 您每次都从 pfx 格式导入证书。

证书的私钥根据标志存储在容器中。因此,如果您使用错误的标志,您可能无法访问它。 DefaultKeySet不仅仅是UserKeySet( msdn ) 的别名 - 所以在每种情况下都选择适当的标志。

这些文章也可能会有所帮助:

  1. 密钥存储和检索
  2. 在 .NET 中使用 X.509 证书的八个技巧
  3. 证书的工作原理
于 2014-07-17T21:33:16.740 回答
1

我发现无论出于何种原因,它都不允许您正确授予密钥权限。为了解决这个问题,我去了:

X:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys

在资源管理器中找到了有问题的密钥(我使用了按日期推断,但指纹在那里,所以你应该能够匹配它。)然后右键单击,接管文件权限,然后手动设置权限。

然后我的代码才开始工作。

然而有趣的是,在我需要将其部署到的另一台机器上,该文件在 machinekeys 目录中不存在,所以我不知道我将在那里做什么,但是......

于 2012-11-22T13:48:45.990 回答