如何解决C#使用.pem文件验证服务器证书
我看到将HTTP请求发送到启用SSL的API时遇到问题。 我收到的错误消息是-
AuthenticationException: The remote certificate is invalid according to the validation procedure.
根据此请求
using (HttpResponseMessage res = client.GetAsync("https://example.com").Result)
{
using (HttpContent content = res.Content)
{
string data = content.ReadAsStringAsync().Result;
if (data != null)
{
Console.WriteLine(data);
}
else
{
Console.WriteLine("Nothing returned");
}
}
}
已给我一个.pem文件,以验证发送回的证书是否已由我们的CA签名,并且在弄清楚如何在C#中执行该操作时遇到了一些麻烦
在python中,我可以通过将.pem文件传递给verify参数来解决证书错误。
r = requests.post(url="https://example.com",headers=headers,verify='mypem.pem')
Dotnet Core 3的HttpClient中是否有等效的东西?
感谢您的帮助!
解决方法
如果由于某种原因不能将证书设置为受信任的,则可以绕过证书验证并亲自验证服务器。不幸的是,它在.NET中不够优雅,并且可能无法在所有平台上使用。请参阅this answer上的bypass invalid SSL certificate in .net core,以获取更多讨论。
using (var httpClientHandler = new HttpClientHandler())
{
// Override server certificate validation.
httpClientHandler.ServerCertificateCustomValidationCallback = VerifyServerCertificate;
// ^ if this throws PlatformNotSupportedException (on iOS?),then you have to use
//httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
// ^ docs: https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.dangerousacceptanyservercertificatevalidator?view=netcore-3.0
using (var client = new HttpClient(httpClientHandler))
{
// Make your request...
}
}
我认为回调的这种实现可以实现您所需的“固定”CA。从this answer到Force HttpClient to trust single Certificate,还有我的更多评论。 编辑:该答案的状态检查不起作用,但每个由this answer链接的人杰里米·法默(Jeremy Farmer),应采用以下方法:
static bool VerifyServerCertificate(HttpRequestMessage sender,X509Certificate2 certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
{
try
{
// Possibly required for iOS? :
//if (chain.ChainElements.Count == 0) chain.Build(certificate);
// https://forums.xamarin.com/discussion/180066/httpclienthandler-servercertificatecustomvalidationcallback-receives-empty-certchain
// ^ Sorry that thread is such a mess! But please check it.
// Without having your PEM I am not sure if this approach to loading the cert works,but there are other ways. From the doc:
// "This constructor creates a new X509Certificate2 object using a certificate file name. It supports binary (DER) encoding or Base64 encoding."
X509Certificate2 ca = new X509Certificate2("mypem.pem");
X509Chain chain2 = new X509Chain();
chain2.ChainPolicy.ExtraStore.Add(ca);
// "tell the X509Chain class that I do trust this root certs and it should check just the certs in the chain and nothing else"
chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
// This setup does not have revocation information
chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
// Build the chain and verify
var isValid = chain2.Build(certificate);
var chainRoot = chain2.ChainElements[chain2.ChainElements.Count - 1].Certificate;
isValid = isValid && chainRoot.RawData.SequenceEqual(ca.RawData);
Debug.Assert(isValid == true);
return isValid;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return false;
}
抱歉,我目前无法对此进行测试,但希望对您有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。