2012-09-23 9 views
63

Ich habe Probleme, meine Windows 8-Anwendung über SSL mit meiner Test-Web-API zu kommunizieren.Zulassen von nicht vertrauenswürdigen SSL-Zertifikaten mit HttpClient

Es scheint, dass HttpClient/HttpClientHandler nicht bietet und Option, nicht vertrauenswürdige Zertifikate zu ignorieren, wie WebRequest ermöglicht Ihnen (wenn auch auf eine "Hacky" Weise mit ServerCertificateValidationCallback).

Jede Hilfe wäre sehr willkommen!

+0

Wenn Sie .NET Core verwenden, könnten Sie sich für [this] (https://stackoverflow.com/a/44540071/5549643) Antworten interessieren. – kdaveid

Antwort

11

Mit Windows 8.1 können Sie jetzt ungültigen SSL-Zertifikaten vertrauen. Sie müssen entweder Windows.Web.HttpClient verwenden oder System.Net.Http verwenden.Httpclient, können Sie den Message-Handler-Adapter verwenden schrieb ich: http://www.nuget.org/packages/WinRtHttpClientHandler

Docs auf der GitHub sind: https://github.com/onovotny/WinRtHttpClientHandler

+4

Gibt es eine Möglichkeit, dies zu tun, ohne all Ihren Code zu verwenden? Mit anderen Worten, was ist der Kern Ihrer Lösung? – wensveen

+0

Der Kern der Lösung besteht darin, den Windows-HTTP-Clienthandler zu umbrechen und diesen als Implementierung des HttpClient zu verwenden. Es ist alles in dieser Datei: https://github.com/onovotny/WinRtHttpClientHandler/blob/master/WinRtHttpClientHandler/WinRtHttpClientHandler.cs fühlen Sie sich frei, es zu kopieren, aber nicht sicher, warum nicht nur das Paket verwenden. –

57

Werfen Sie einen Blick auf die WebRequestHandler Class und seine ServerCertificateValidationCallback Property:

using (var handler = new WebRequestHandler()) 
{ 
    handler.ServerCertificateValidationCallback = ... 

    using (var client = new HttpClient(handler)) 
    { 
     ... 
    } 
} 
+4

Danke für die Antwort, aber ich habe schon darüber nachgedacht - es ist nicht in .NET für Windows 8 Store-Apps vorhanden. – Jamie

+0

Das Erstellen einer eigenen abgeleiteten Klasse HttpClientHandler oder HttpMessageHandler ist jedoch einfach genug, insbesondere angesichts der Tatsache, dass die WebRequestHandler-Quelle verfügbar ist. –

+0

@ ThomasS.Trias irgendeine Probe darüber? 'abgeleitete Klasse'? – Kiquenet

4

Wenn dies für eine Windows-Runtime-Anwendung ist, dann müssen Sie das selbst signierte Zertifikat in das Projekt ein und es in der appxmanifest verweisen.

Die docs sind hier: http://msdn.microsoft.com/en-us/library/windows/apps/hh465031.aspx

Das Gleiche gilt, wenn es von einer Zertifizierungsstelle ist, die (wie ein privater CA, dass die Maschine selbst nicht traut) nicht vertrauenswürdig sind - Sie die öffentlichen CERTs CA erhalten müssen, Füge es als Inhalt zur App hinzu und füge es dann zum Manifest hinzu.

Sobald dies erledigt ist, wird die App es als korrekt signiert Cert sehen.

2

Ich habe keine Antwort, aber ich habe eine Alternative.

Wenn Sie Fiddler2 verwenden, um den Datenverkehr zu überwachen und die HTTPS-Entschlüsselung zu aktivieren, wird sich Ihre Entwicklungsumgebung nicht beschweren. Dies funktioniert nicht auf WinRT-Geräten wie Microsoft Surface, da Sie keine Standard-Apps darauf installieren können. Aber Ihre Entwicklung Win8 Computer wird in Ordnung sein.

Um die HTTPS-Verschlüsselung in Fiddler2 zu aktivieren, gehen Sie zu Extras> Fiddler-Optionen> HTTPS (Registerkarte)> Aktivieren Sie "HTTPS-Verkehr entschlüsseln".

Ich werde diesen Thread im Auge behalten, in der Hoffnung, dass jemand eine elegante Lösung hat.

83

Eine schnelle und schmutzige Lösung besteht darin, den Delegierten ServicePointManager.ServerCertificateValidationCallback zu verwenden. Auf diese Weise können Sie Ihre eigene Zertifikatsprüfung bereitstellen. Die Validierung wird global in der gesamten App Domain angewendet.

ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true; 

Ich benutze dies in erster Linie für Unit-Tests in Situationen, in denen ich vor einem Endpunkt ausgeführt werden soll, dass ich dabei bin Hosting in und sind versucht, es zu treffen mit einem WCF client oder HttpClient.

Für Produktionscode möchten Sie vielleicht mehr feinkörnige Kontrolle und wäre besser dran mit der WebRequestHandler und seine ServerCertificateValidationCallback Delegierten-Eigenschaft (Siehe dtb's answer below).

+22

Nicht der Downvoter, aber eines der größten Probleme mit dem ServerCertificateValidationCallback ist, dass es im Grunde global für Ihre AppDomain ist. Wenn Sie also eine Bibliothek schreiben, die eine Site mit einem nicht vertrauenswürdigen Zertifikat aufruft und diese Problemumgehung verwendet, ändern Sie das Verhalten der gesamten Anwendung, nicht nur Ihrer Bibliothek. Auch sollten Menschen immer vorsichtig sein mit dem "Blind Return True" -Ansatz. Es hat ernsthafte Auswirkungen auf die Sicherheit. Er sollte lesen/* die gelieferten Parameter überprüfen und dann sorgfältig entscheiden, ob */wahr zurückgibt; – scottt732

+0

@ scottt732 Sicherlich ein gültiger Punkt und erwähnenswert, aber es ist immer noch eine gültige Lösung. Vielleicht nach dem Lesen der ursprünglichen Frage durch die OP scheint es, er war bereits der ServerCertificateValidationCallback Handler bekannt – Bronumski

+2

Ich würde empfehlen, zumindest auf einige Kriterien wie Absender zu filtern –

20

Oder können Sie für die Httpclient im Windows.Web.Http Namespace verwenden:

var filter = new HttpBaseProtocolFilter(); 
#if DEBUG 
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired); 
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted); 
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName); 
#endif 
using (var httpClient = new HttpClient(filter)) { 
    ... 
} 
+0

Kann ich 'System.Net.Http',' System.Web' und 'Windows.Web.Http' zusammen verwenden? – Kiquenet

0

Ich habe ein Online-Beispiel gefunden, das gut zu funktionieren scheint:

Zuerst erstellen Sie eine neue ICertificatePolicy

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

public class MyPolicy : ICertificatePolicy 
{ 
    public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, 
int certificateProblem) 
    { 
    //Return True to force the certificate to be accepted. 
    return true; 
    } 
} 

Verwenden Sie dann nur diese, bevor Sie HTTP-Anfrage an das Senden wie so:

System.Net.ServicePointManager.CertificatePolicy = new MyPolicy(); 

http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/

+0

'ServicePointManager.CertificatePolicy' ist veraltet: https://docs.microsoft.com/de-de/dotnet/framework/whats-new/obsolete-members – schmidlop

3

Wenn Sie versuchen, diese Bibliothek in einer .NET-Norm zu tun, hier ist ein einfache Lösung, mit allen Risiken der Rückkehr true in Ihrem Handler. Ich überlasse dir Sicherheit.

var handler = new HttpClientHandler(); 
handler.ClientCertificateOptions = ClientCertificateOption.Manual; 
handler.ServerCertificateCustomValidationCallback = 
    (httpRequestMessage, cert, cetChain, policyErrors) => 
{ 
    return true; 
}; 

var client = new HttpClient(handler); 
+0

Dies führt dazu, dass die Plattform nicht unterstützt wird, wenn sie von uwp referenziert wird – Ivan

Verwandte Themen