31 Stimmen

Holen Sie sich ein SSL-Zertifikat in .NET

Ich möchte die Daten des SSL-Zertifikats von beliebigen Domainnamen abrufen. Zum Beispiel möchte ich eine beliebige Website-Adresse eingeben, z.B. "http://stackoverflow.com", und mein Code würde zunächst überprüfen, ob ein SSL-Zertifikat vorhanden ist. Falls ja, möchte ich das Ablaufdatum des Zertifikats auslesen. [Ich lese Domainnamen aus der Datenbank] Beispiel: http://www.digicert.com/help/

Ich muss einen Webservice erstellen, um das Ablaufdatum zu überprüfen. Wie kann ich das umsetzen? - Ich habe mir viele verschiedene Dinge wie RequestCertificateValidationCallback und ClientCertificates angesehen.

Ich könnte völlig falsch liegen (deshalb brauche ich Hilfe), aber würde ich einen HTTPWebRequest erstellen und dann irgendwie das Client-Zertifikat und bestimmte Elemente auf diese Weise anfordern?

Ich habe das Beispiel unter SSL-Zertifikat vorab abrufen .NET probiert, aber ich bekomme einen 403-Fehler.

42voto

cdev Punkte 4245

Um dies zu erreichen, benötigt Ihr Projekt einen Verweis auf System.Security:

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

// Webanfrage zum Abrufen von Informationen über sichere Website
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://mail.google.com");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();

// Das SSL-Zertifikat abrufen und einem X509Certificate-Objekt zuweisen
X509Certificate cert = request.ServicePoint.Certificate;

// Das X509Certificate in ein X509Certificate2-Objekt konvertieren, indem es dem Konstruktor übergeben wird
X509Certificate2 cert2 = new X509Certificate2(cert);

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

// Das Zertifikatdialogfeld anzeigen
X509Certificate2UI.DisplayCertificate(cert2);

.NET Core 2.1 - .NET 5

Sie können HttpClientHandler und die Eigenschaft ServerCertificateCustomValidationCallback verwenden. (Diese Klasse ist auch in .NET 4.7.1 und höher verfügbar).

var handler = new HttpClientHandler
{
     UseDefaultCredentials = true,

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

          // Auf das Zertifikatsobjekt zugreifen.

          return true;
     }
 };

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

          }
      }
 }

16voto

Poulad Punkte 1139

@cdev's Lösung hat für mich nicht auf .NET Core 2.1 funktioniert. Es scheint, dass HttpWebRequest auf .NET Core nicht vollständig unterstützt wird.

Hier ist die Funktion, die ich auf .NET Core verwende, um das X509-Zertifikat eines beliebigen Servers zu erhalten:

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

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

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

    return zertifikat ?? throw new NullReferenceException();
}

5voto

user60177 Punkte 51

Eine Sache, die zu beachten ist, ist dass du möglicherweise request.AllowAutoRedirect = False setzen musst. Andernfalls, wenn der Server von HTTPS auf HTTP umleitet, wirst du das Zertifikat nicht vom HttpWebRequest-Objekt erhalten können.

1voto

Isybycnsmam Punkte 21

Es ist sehr ineffektiv und kann Leistungsprobleme verursachen, den HttpClient jedes Mal neu zu erstellen, wenn Sie eine Anfrage stellen möchten. Besser ist es, einen einzelnen schreibgeschützten Client für alle Methoden zu erstellen. Weitere Informationen finden Sie hier.

private readonly HttpClientHandler _handler;
private readonly HttpClient _client;

Und das ist meine Lösung, um Zertifikatsinformationen zu erhalten:

Code im Konstruktor:

 _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);

Dann können Sie alle Variablen lesen, indem Sie:

using var request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com/");
var response = await _client.SendAsync(request);
var isCertificateValid = (bool)request.Properties["Valid"];

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X