📅  最后修改于: 2023-12-03 14:48:25.216000             🧑  作者: Mango
有时候在使用 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;
}
};