📜  Web 客户端忽略 ssl 错误 - C# (1)

📅  最后修改于: 2023-12-03 14:48:25.216000             🧑  作者: Mango

Web 客户端忽略 SSL 错误 - C#

有时候在使用 C# 中的 Web 客户端请求 HTTPS 地址时,会出现 SSL 证书验证失败的问题。这可能是因为服务器没有正确配置 SSL 证书,或者证书过期等原因。在这种情况下,可以使用以下方法忽略 SSL 错误,继续发送请求。

方法一:取消证书验证

这种方法虽然简单,但是存在安全风险。因为取消证书验证后,请求可能会被劫持,而我们完全不知道。

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

或者在 .NET Framework 4.5+ 中可以使用以下方式:

HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
HttpClient client = new HttpClient(handler);
方法二:添加自定义证书

通过添加自定义证书,我们可以在不取消证书验证的情况下,进行正常的 HTTPS 请求。首先将自定义证书放到项目的根目录下,然后使用以下代码进行添加。

ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors || sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
    {
        if (chain != null && chain.ChainStatus != null)
        {
            foreach (X509ChainStatus status in chain.ChainStatus)
            {
                if ((certificate.Subject == certificate.Issuer) && (status.Status == X509ChainStatusFlags.UntrustedRoot))
                {
                    //自签名证书,且在计算机的受信任的根证书颁发机构中没有证书 
                    continue;
                }
                else
                {
                    if (status.Status == X509ChainStatusFlags.NoError)
                    {
                        continue;
                    }
                    else
                    {
                        if ((status.Status == X509ChainStatusFlags.UntrustedRoot && chain.ChainElements[chain.ChainElements.Count - 1].Certificate.RawData.SequenceEqual(certBytes))
                            || status.Status == X509ChainStatusFlags.PartialChain)
                        {
                            //受信任的根证书颁发机构(没有为自签名证书) 或 部分信任
                            continue;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
};
方法三:信任指定的证书

这种方法比较好,因为只有我们信任的证书才会被接受。首先需要将证书放到项目的根目录下,然后使用以下代码进行信任。

ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }
    else
    {
        string sitePath = HttpContext.Current.Server.MapPath("~");
        string cerPath = sitePath + System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().CodeBase) + "-ssl.cer";
        if (System.IO.File.Exists(cerPath))
        {
            X509Certificate cer = new X509Certificate2(cerPath);
            if (cer.Thumbprint == certificate.GetCertHashString())
            {
                return true;
            }
        }
        return false;
    }
};