首页 文章

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

提问于
浏览
6

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

SystemError:基础连接已关闭:无法为SSL / TLS安全通道 Build 信任关系 .

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

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

2 回答

  • 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

    我最终实现的解决方案是编写一个使用自定义验证逻辑实现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 .

相关问题