26

我希望从任何给定的域名 SSL 证书中获取数据。例如,我想输入任何网站地址,例如“ http://stackoverflow.com ”,我的代码将首先检查 SSL 证书是否存在。如果是这样,那么我希望它提取证书的到期日期。[我正在从 DB 读取域名] 示例:http ://www.digicert.com/help/

我需要创建一个 Web 服务来检查到期日期。我该如何实施?- 我查看了很多不同的东西,例如 RequestCertificateValidationCallback 和 ClientCertificates 等。

我可能完全错了(因此我需要帮助)但是我会创建一个 HTTPWebRequest 然后以某种方式请求客户端证书和特定元素吗?

我尝试了提供@ SSL 证书预取 .NET的示例,但我收到了被禁止的 403 错误。

4

4 回答 4

37

为此,您的项目需要参考System.Security

using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

//Do webrequest to get info on secure site
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://mail.google.com");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();

//retrieve the ssl cert and assign it to an X509Certificate object
X509Certificate cert = request.ServicePoint.Certificate;

//convert the X509Certificate to an X509Certificate2 object by passing it into the constructor
X509Certificate2 cert2 = new X509Certificate2(cert);

string cn = cert2.GetIssuerName();
string cedate = cert2.GetExpirationDateString();
string cpub = cert2.GetPublicKeyString();

//display the cert dialog box
X509Certificate2UI.DisplayCertificate(cert2);

.NET 核心 2.1 - .NET 5

您可以使用HttpClientHandlerServerCertificateCustomValidationCallback属性。(此类在 .net 4.7.1 及更高版本中也可用)。

var handler = new HttpClientHandler
{
     UseDefaultCredentials = true,

     ServerCertificateCustomValidationCallback = (sender, cert, chain, error) =>
     {

          /// Access cert object.

          return true;
     }
 };

 using (HttpClient client = new HttpClient(handler))
 {
     using (HttpResponseMessage response = await client.GetAsync("https://mail.google.com"))
     {
          using (HttpContent content = response.Content)
          {

          }
      }
 }
于 2013-03-11T16:42:10.513 回答
13

@cdev 的解决方案在 .NET Core 2.1 上对我不起作用。.NET Core似乎HttpWebRequest完全支持它。

这是我在 .NET Core上用来获取任何服务器的 X509 证书的函数:

// using System;
// using System.Net.Http;
// using System.Security.Cryptography.X509Certificates;
// using System.Threading.Tasks;

static async Task<X509Certificate2> GetServerCertificateAsync(string url)
{
    X509Certificate2 certificate = null;
    var httpClientHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (_, cert, __, ___) =>
        {
            certificate = new X509Certificate2(cert.GetRawCertData());
            return true;
        }
    };

    var httpClient = new HttpClient(httpClientHandler);
    await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));

    return certificate ?? throw new NullReferenceException();
}
于 2019-01-06T17:10:58.227 回答
5

需要注意的一件事是,您可能需要设置request.AllowAutoRedirect = False. 否则,如果服务器将 HTTPS 重定向到 HTTP,您将无法从HttpWebRequest对象中获取证书。

于 2015-02-09T03:46:09.863 回答
0

每次HttpClient要发出请求时都重新创建非常无效,并且可能会导致性能问题。最好为所有方法创建一个只读客户端。更多信息可以在这里找到。

private readonly HttpClientHandler _handler;
private readonly HttpClient _client;

这是我获取证书信息的解决方案:

构造函数内的代码:

 _handler = new HttpClientHandler {
    ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
    {
        sender.Properties.Add("Valid", sslPolicyErrors == System.Net.Security.SslPolicyErrors.None);
        sender.Properties.Add("Errors", sslPolicyErrors);
        return true;
    }
 };
 _client = new HttpClient(_handler);

然后您可以通过以下方式读取所有变量:

using var request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com/");
var response = await _client.SendAsync(request);
var isCertificateValid = (bool)request.Properties["Valid"];
于 2020-06-09T01:22:48.517 回答