Wie verwende ich WebRequest, um über https auf eine SSL-verschlüsselte Site zuzugreifen?


116

Ich schreibe ein Programm, das Inhalte von einer vom Benutzer angegebenen URL liest. Mein Problem liegt in dem Code, der ungefähr so ​​lautet:

Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
WebResponse webResponse = webRequest.GetResponse();
ReadFrom(webResponse.GetResponseStream());

Und dies ist fehlerhaft, wenn die angegebene URL eine "https: //" - URL ist. Kann mir jemand helfen, diesen Code so zu ändern, dass er mit SSL-verschlüsselten Inhalten funktioniert? Vielen Dank.

Antworten:


175

Sie machen es richtig, aber Benutzer geben möglicherweise URLs für Websites an, auf denen ungültige SSL-Zertifikate installiert sind. Sie können diese Zertifizierungsprobleme ignorieren, wenn Sie diese Zeile eingeben, bevor Sie die eigentliche Webanforderung stellen:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

wo AcceptAllCertificationsist definiert als

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

41
Danke für diese Antwort! Um nutzlosen Code zu vermeiden, habe ich ihn folgendermaßen verwendet: ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
— Charles Ouellet

4
Danke, Sie haben mir geholfen, Sir. F # macht dies so einfacher:ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true)
— David Grenier

2
@ Charles Ouellet Ich denke, ich bin noch fauler als Sie, (a, b, c, d) => wahr
— Despertar

24
Ich bevorzuge+= delegate { return true; }
— vkrzv

2
Seien Sie sich der potenziellen Risiken bewusst, die mit diesem Ansatz verbunden sind. Weitere Informationen finden Sie unter stackoverflow.com/a/6613434/2969615 .
— Joe Coyle

19

Dieser Link ist für Sie von Interesse: http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

Bei http-Verbindungen verwenden die Klassen WebRequest und WebResponse SSL, um mit Webhosts zu kommunizieren, die SSL unterstützen. Die Entscheidung für die Verwendung von SSL wird von der WebRequest-Klasse basierend auf dem angegebenen URI getroffen. Wenn der URI mit "https:" beginnt, wird SSL verwendet. Wenn der URI mit "http:" beginnt, wird eine unverschlüsselte Verbindung verwendet.


Toller Link. Das ist ein wichtiger Unterschied.
— DanM7

1
Ihre Antwort impliziert, dass der Code in der Frage funktionieren sollte?
— Rowland Shaw

18

Dieser hat für mich gearbeitet:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

1
Der Standardwert ist "Ssl2 | Tls". Ich hatte nur Tls 1.1 und 1.2 auf meinem Server aktiviert. Dies hat das Problem tatsächlich behoben! Für LetsEncrypt mit nginX unter Linux werden die Protokolle hier definiert: /etc/letsencrypt/options-ssl-nginx.conf
— Jerther

Ich glaube, das ist ein anderes Thema. Es geht nicht um ungültige Zertifikate, sondern um höhere TLS-Versionen.
— wp78de

Ich bekam "Eine bestehende Verbindung wurde vom Remote-Host zwangsweise geschlossen" und diese Lösung funktionierte für mich
— oamilkar

Beachten Sie, dass dies eine globale Konfiguration ist, sodass Sie dies nur einmal und nicht jedes Mal tun müssen, wenn Sie die Anforderung einrichten.
— Chad Hedgcock

Kann ich das irgendwie für eine einzelne Anfrage tun? Es scheint, dass ServicePointManager eine ziemlich globale Sache ist ...
— wexman
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.