wake-up-neo.com

Wie können Sie WebClient (C #) ein Zertifikat hinzufügen?

Ich weiß, dass es ziemlich einfach ist, ein Zertifikat zu einer HttpWebRequest hinzuzufügen. Ich habe jedoch keine Möglichkeit gefunden, dies mit WebClient zu erreichen. Grundsätzlich möchte ich mit WebClient ein POST mit einem bestimmten Zertifikat versenden.

Wie würden Sie genau diesen Code mit WebClient erreichen:

    var request = (HttpWebRequest) WebRequest.Create("my-url");
    request.Method = "POST";
    request.ClientCertificates.Add(new X509Certificate()); //add cert
69
Andrew

Sie müssen eine oder mehrere Funktionen in Unterklassen unterteilen und überschreiben.

class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        request.ClientCertificates.Add(new X509Certificate());
        return request;
    }
}
88
Mikael Svenson
public class CertificateWebClient : WebClient
{
    private readonly X509Certificate2 certificate;

    public CertificateWebClient(X509Certificate2 cert)
    {
        certificate = cert;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);

        System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate X509certificate, X509Chain chain, System.Net.Security.SslPolicyErrors errors)
        {
            return true;
        };

        request.ClientCertificates.Add(certificate);
        return request;
    }
}

Jetzt können Sie mit selbst signiertem Zertifikat! ("Die zugrunde liegende Verbindung wurde geschlossen: Konnte keine Vertrauensstellung für den sicheren SSL/TLS-Kanal herstellen.; Die zugrunde liegende Verbindung wurde geschlossen: Konnte keine Vertrauensstellung für den sicheren SSL/TLS-Kanal herstellen.;")

        X509Certificate2 Cert = new X509Certificate2("client.p12", "1234", X509KeyStorageFlags.MachineKeySet);

        // Create a new WebClient instance.
        CertificateWebClient myWebClient = new CertificateWebClient(Cert);

        string fileName = Installation.destXML;
        string uriString = "https://xxxxxxx.xx:918";
        // Upload the file to the URI.
        // The 'UploadFile(uriString,fileName)' method implicitly uses HTTP POST method.
        byte[] responseArray = myWebClient.UploadFile(uriString, fileName);

        // Decode and display the response.
        Console.WriteLine("\nResponse Received.The contents of the file uploaded are:\n{0}",
            System.Text.Encoding.ASCII.GetString(responseArray));
10
yop038

Eine interessante Sache ist passiert, als ein neues Zertifikat auf unseren Frontends installiert wurde. Wir bekamen den Fehler:

"Die zugrunde liegende Verbindung wurde geschlossen: Konnte keine Vertrauensstellung für den sicheren SSL/TLS-Kanal herstellen.; Die zugrunde liegende Verbindung wurde geschlossen: Konnte keine Vertrauensstellung für den sicheren SSL/TLS-Kanal herstellen.;"

Wir haben uns um den Fehler gekümmert, indem wir zu jedem Front-End gegangen sind und den Browser geöffnet haben. Es scheint, dass IE das alte Zertifikat zwischengespeichert hat. Durch das Öffnen der Browser wurde das neue Zertifikat wirksam. Problem gelöst!

4
Jose

Unterklasse einfach WebClient, füge deine eigene ClientCertificates -Eigenschaft hinzu und überschreibe die WebClient.GetWebRequest(System.Uri) -Methode. Ich habe keine Zeit, dies in C # von VB zu konvertieren, aber es sollte ziemlich selbsterklärend sein:

Imports System.Net

Public Class WebClient2
    Inherits System.Net.WebClient

    Private _ClientCertificates As New System.Security.Cryptography.X509Certificates.X509CertificateCollection
    Public ReadOnly Property ClientCertificates() As System.Security.Cryptography.X509Certificates.X509CertificateCollection
        Get
            Return Me._ClientCertificates
        End Get
    End Property
    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
        Dim R = MyBase.GetWebRequest(address)
        If TypeOf R Is HttpWebRequest Then
            Dim WR = DirectCast(R, HttpWebRequest)
            If Me._ClientCertificates IsNot Nothing AndAlso Me._ClientCertificates.Count > 0 Then
                WR.ClientCertificates.AddRange(Me._ClientCertificates)
            End If
        End If
        Return R
    End Function
End Class
4
Chris Haas