带有x509证书的HttpClient请求适用于Debug但在生产中失败(403禁止)

时间:2012-11-16 14:53:52

标签: c# x509certificate2 dotnet-httpclient

我有一个黑盒子服务,我必须使用返回xml的简单rest命令调用。

他们向我们颁发了证书,必须在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禁止。

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

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

谢谢!

2 个答案:

答案 0 :(得分:3)

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

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

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

2)LocalSystem下的Windows服务,NetworkService下的IIS或内置Windows帐户的其他服务,您应该使用

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

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

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

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

  1. Key Storage and Retrieval
  2. Eight tips for working with X.509 certificates in .NET
  3. How Certificates Work

答案 1 :(得分:1)

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

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

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

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

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