【问题标题】:Check SSL-Certifacte expiration date without authorization未经授权检查 SSL 证书到期日期
【发布时间】:2016-07-20 11:14:07
【问题描述】:

到目前为止,我能够获得无需使用用户名和密码授权的网页 SSL 证书的到期日期:

class Program
{
  static void ReadExpirDate()
  {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com");
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    response.Close();

    X509Certificate cert = request.ServicePoint.Certificate;
    X509Certificate2 cert2 = new X509Certificate2(cert);

    string cedate = cert2.GetExpirationDateString();
    Console.WriteLine(cedate);
  }
}

但是,如果我尝试获取需要使用用户名和密码授权才能访问它的网页的到期日期,我会收到 System.Net.WebException "error:(401) Unauthorized" 异常。 有没有办法获取 SSL 证书的到期日期?

【问题讨论】:

    标签: c# ssl ssl-certificate


    【解决方案1】:

    这一行:

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    

    实际上是在调用未经授权的指定 Url,这就是引发异常的地方,如果你这样做,那么你可以使用返回的 request 中的 Certificate 属性,尽管 Exception:

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com");
        X509Certificate cert2 = null;
        HttpWebResponse response =null;
    
        try {
            response = (HttpWebResponse)request.GetResponse();
            X509Certificate cert = request.ServicePoint.Certificate;
            cert2 = new X509Certificate2(cert);
        } catch {
            X509Certificate cert = request.ServicePoint.Certificate;
            cert2 = new X509Certificate2(cert);
        } finally {
            response.Close();
        }
    
        if (cert2 != null) {
            string cedate = cert2.GetExpirationDateString();
            Console.WriteLine(cedate);
        }
    

    此代码将受到更好的异常处理和重构,但它应该可以工作。

    【讨论】:

    • 当我遗漏了响应部分时,我没有得到未经授权的异常是的。但是现在我在“X509Certificate2 cert2 = new X509Certificate2(cert);”行中遇到了一个异常因为证书为空。
    • 啊,我的错,我认为在这种情况下,您应该只获取 URL 的主机部分的证书,而不是完整的页面 URL?除非您知道在您的情况下这行不通?
    • 嗯,我认为主要问题是我尝试从中获取证书的站点在您登录之前没有加载。所以我永远不会得到它的完整回复。我想我需要寻找机会在没有响应的情况下获得证书。例如。在我的浏览器中,我无需登录网站即可手动查找证书。
    • 您能否举例说明您仅从 URL 的主机部分获取证书是什么意思?
    • var uri = new Uri("google.com/somerestrictedresource.html"); requestUri = uri.Scheme + uri.Authority; 那么您将获得“google.com”的证书,您将能够发出请求,如果整个主机都经过身份验证(可能是纯 API 服务器),那么我不确定这是可能的。
    【解决方案2】:

    授权前使用ServerCertificateValidationCallback获取证书

    var request = (HttpWebRequest)WebRequest.Create(GetOptionValue("url"));
    
    request.ServerCertificateValidationCallback += delegate
        (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
         System.Security.Cryptography.X509Certificates.X509Chain chain,
         System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
             string expirationDate = certificate.GetExpirationDateString();
             return true;
        }
    

    【讨论】:

    • 从 .NET Core 1.0 及更高版本(包括 .NET 5.0 及更高版本)开始,Certificate 属性始终返回 null。 ServerCertificateCustomValidationCallback 是访问服务器证书的推荐方式。 docs.microsoft.com/en-us/dotnet/api/…
    猜你喜欢
    • 2012-03-29
    • 2019-11-08
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2020-05-20
    • 2012-03-19
    相关资源
    最近更新 更多