我正在尝试为类ServerCertificateCustomValidationCallback
的实例实现一种方法HttpClientHandler
。我在这里不知所措,因为我不知道要验证什么。我需要向服务器发送证书(我已经这样做了),并验证服务器发送给我的证书。我已经看到了这个和这个实现,它们告诉我将收到的证书与已知值进行比较。我不确定如何获得这个已知值,我知道我在LocalMachine 的 Trusted root store中安装了一个受信任的证书,我是否应该期望链中的证书包含与我安装的证书相同的哈希?
这是我到目前为止所拥有的:
private HttpClientHandler CreateHandler()
{
var handler = new HttpClientHandler
{
SslProtocols = SslProtocols.Tls12
};
var certPath = System.Configuration.ConfigurationManager.AppSettings["MY_CERT_PATH"];
handler.ClientCertificates.Add(new X509Certificate2(Path.Combine(certPath, "tls.pfx")));
handler.CheckCertificateRevocationList = true;
handler.ServerCertificateCustomValidationCallback = ValidateServerCertificate;
return handler;
}
private bool ValidateServerCertificate(HttpRequestMessage message, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors policy)
{
if (policy == SslPolicyErrors.None)
return true;
using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
foreach (var element in chain.ChainElements)
{
var hashes = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, element.Certificate.Subject, true)
.Cast<X509Certificate2>()
.Select(cert => cert.GetCertHashString(HashAlgorithmName.SHA512));
var hash = element.Certificate.GetCertHashString(HashAlgorithmName.SHA512);
if (hashes.Any(h => h == hash))
return true;
}
store.Close();
}
return false;
}