如何使用 C# 验证 SSL 证书 [英] How to validate a SSL certificate with C#

查看:62
本文介绍了如何使用 C# 验证 SSL 证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

maybe one of you can help me answer my question about validating certificates in the .NET framework. Unfortunately I found only superficial answers to my questions during my research on the Internet, but no exact explanation.

Meanwhile I know that I can check in my software with the following code whether a certificate is valid.

ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

private bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
   return policyErrors == SslPolicyErrors.None;
}

But I would now like to know what Microsoft is checking here exactly? What checks were performed by the framework to make the result SslPolicyErrors.None?

For example, is the root certificate also validated here and where it comes from? If so, how?

In your opinion is it still necessary (or useful) to add additionally my own checks to these checks, which the .NET Framework hasn't made yet?

解决方案

This is partially just a repeat of c# Validating an X509Certificate2: am I doing this right?, the short form answer from there is that the checks you get for free (with no custom handler, or that are already done before your handler):

  • The certificate chain is valid (otherwise SslPolicyErrors.RemoteCertificateChainErrors is set)
    • The certificate chains up to a trusted root authority
    • The certificate is not expired (or from the future)
    • The certificate indicates that it is intended to be used as a TLS server certificate
    • If revocation was enabled on the request (it's off by default), no certs in the chain are revoked.
  • The certificate applies to the hostname you were connecting to (otherwise SslPolicyErrors.RemoteCertificateNameMismatch is set)

For example, is the root certificate also validated here and where it comes from?

The certificate verification here uses the same root trust list as Internet Explorer, Chrome, Edge, Outlook, et cetera use, which is centrally managed in Windows. (Firefox uses a different root trust list, which is managed only by Firefox.)

In your opinion ...

Opinion questions are off-topic on StackOverflow.

it still necessary (or useful) to add additionally my own checks to these checks, which the .NET Framework hasn't made yet?

That depends.

If you are contacting one of your own servers, and you know something to expect about the certificate chain, you could add an extra check. For example, you could know that your server uses Let's Encrypt, and you embed in your application both "Let’s Encrypt Authority X3" certificates from https://letsencrypt.org/certificates/ then you could pin the intermediate... you just need to be sure to react when they move to a new intermediate.

private bool ValidateRemoteCertificate(
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors policyErrors)
{
    if (policyErrors != SslPolicyErrors.None)
    {
        return false;
    }

    if (chain.ChainElements.Count != 3)
    {
        return false;
    }

    byte[] foundCert = chain.ChainElements[1].Certificate.RawData;

    return s_letsEncryptX3Direct.SequenceEqual(foundCert) ||
        s_letsEncryptX3Cross.SequenceEqual(foundCert);
}

If you're not going to perform additional checks (or do custom logging, et cetera) then it's better to not even register the callback, because the implementation is a bit nicer with memory and CPU when there's no callback registered.

这篇关于如何使用 C# 验证 SSL 证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆