如何将可信CA证书(不是客户端证书)添加到HttpWebRequest?

时间:2012-02-29 23:34:48

标签: .net httpwebrequest certificate

我编写了一个使用HttpWebRequest连接到HTTPS站点的C#程序。 GetResponse()方法抛出异常:

  

SystemError:底层连接已关闭:无法建立   SSL / TLS安全通道的信任关系。

我可以使用curl.exe --cacert CAFile.pem连接到同一个网站。我希望能够使用C#程序中相同的可信CA证书。

如何让HttpWebRequest使用此CA证书文件(或包含从中解析的证书的X509CertificateCollection)?

2 个答案:

答案 0 :(得分:5)

尝试设置ServerCertificateValidationCallback以使用它:

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    return true;

    X509Chain privateChain = new X509Chain();
    privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;

    X509Certificate2 cert2 = new X509Certificate2(certificate);
    X509Certificate2 signerCert2 = new X509Certificate2(@"C:\MyCACert.PEM");

    privateChain.ChainPolicy.ExtraStore.Add(signerCert2);       
    privateChain.Build(cert2);

    bool isValid = true;

    foreach (X509ChainStatus chainStatus in privateChain.ChainStatus)
    {
        if (chainStatus.Status != X509ChainStatusFlags.NoError)
        {
            isValid = false;
            break;
        }
    }

    return isValid;
}

我没有机会对此进行测试,所以如果您遇到任何错误请告诉我,如果需要,我会修改答案。

答案 1 :(得分:1)

我最终实现的解决方案是编写一个实现ICertificatePolicy的类,其中包含自定义验证逻辑:

private X509CertificateCollection   _certs;
private ICertificatePolicy          _defaultPolicy;

public bool CheckValidationResult(ServicePoint svcPoint, X509Certificate cert, WebRequest req, int problem)
{
    if ((_defaultPolicy != null) && _defaultPolicy.CheckValidationResult(svcPoint, cert, req, problem))
    {
        return true;
    }

    foreach (X509Certificate caCert in _certs)
    {
        if (caCert.Equals(cert))
        {
            return true;
        }
    }

    return false;
}

(为简洁起见,省略了错误检查。)

_defaultPolicy可以设置为ServicePointManager.CertificatePolicy,以允许在自定义证书之外使用默认证书存储。

_certs包含额外的证书。它是通过解析PEM文件并调用_certs.Add(new X509Certificate(Convert.FromBase64String(base64cert)));

生成的

CertificatePolicy已被ServerCertificateValidationCallback淘汰,但我需要支持旧版本的.NET。