Problemlösung "Es konnte keine Vertrauensbeziehung für den sicheren SSL / TLS-Kanal mit Berechtigung hergestellt werden"

135

Ich dachte wirklich, ich hätte dieses Problem behoben, aber es wurde nur vorher getarnt.

Ich habe einen WCF-Dienst, der in IIS 7 mithilfe von HTTPS gehostet wird. Wenn ich auf diese Seite in Internet Explorer durchsuchen, es funktioniert wie ein Charme, ist dies , weil ich habe das Zertifikat auf den lokalen Stammzertifizierungsstelle Speicher hinzugefügt.

Ich entwickle auf einem Computer, daher sind Client und Server derselbe Computer. Das Zertifikat ist direkt vom IIS 7-Verwaltungs-Snap-In selbstsigniert.

Ich bekomme jetzt ständig diesen Fehler ...

Es konnte keine Vertrauensbeziehung für den sicheren SSL / TLS-Kanal mit Berechtigung hergestellt werden.

... wenn von der Client-Konsole aus aufgerufen.

Ich habe mir manuell Berechtigungen und Netzwerkdienste für das Zertifikat erteilt, verwendet findprivatekeyund verwendet cacls.exe.

Ich habe versucht, über SOAPUI eine Verbindung zum Dienst herzustellen, und das funktioniert. Daher muss es sich um ein Problem in meiner Clientanwendung handeln, bei dem es sich um Code handelt, der auf dem basiert, was früher mit http funktioniert hat.

Wo sonst kann ich suchen? Ich habe anscheinend alle Möglichkeiten ausgeschöpft, warum ich keine Verbindung herstellen kann.

J L.
quelle
Wenn Sie die Kontrolle über die Erstellung der Zertifikate haben, vergessen Sie nicht "Alternativer Betreffname". Als könnten Sie einen Platzhalter in "* .full.domainname.com" einfügen. Siehe digicert.com/subject-alternative-name.htm
granadaCoder

Antworten:

198

Als Abhilfe können Sie einen Handler für das Add ServicePointManager‚s ServerCertificateValidationCallbackauf der Client - Seite:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (se, cert, chain, sslerror) =>
        {
            return true;
        };

Beachten Sie jedoch, dass dies keine bewährte Methode ist, da das Serverzertifikat vollständig ignoriert wird und dem Service Point Manager mitgeteilt wird, dass jedes Zertifikat in Ordnung ist, was die Client-Sicherheit ernsthaft beeinträchtigen kann. Sie können dies verfeinern und einige benutzerdefinierte Überprüfungen durchführen (für Zertifikatsnamen, Hash usw.). Zumindest können Sie Probleme während der Entwicklung umgehen, wenn Sie Testzertifikate verwenden.

Joachim Kerschbaumer
quelle
9
Ich denke, die meisten öffentlichen Setups verwenden ein gekauftes Zertifikat, aber während der Entwicklung verwenden Sie den obigen Code in bedingten # if-Anweisungen. Unternehmensentwickler sollten im Allgemeinen einen internen CA-Server
einrichten
2
Hat mir geholfen herauszufinden, wie ich meinen SSL-WCF-Aufruf zum Debuggen mit Fiddler2 zum Laufen bringen kann.
Roger Willcocks
2
@karank Erwägen Sie, es in die Application_Start-Methode in Global.asax einzufügen (siehe stackoverflow.com/a/12507094/1175419 ). Ich würde dringend empfehlen, eine # if DEBUG-Compiler-Direktive oder ähnliches zu verwenden, wie in Lukes Kommentar erwähnt.
Rich C
4
Genial! Sie können den Lambda-Ausdruck als System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => true verwenden.
Dhanuka777
Eine kleine zusätzliche Erklärung finden Sie hier: blog.effectivemessaging.com/2015_09_01_archive.html
granadaCoder
40

Wenn ich dieses Problem habe, liegt es daran, dass die client.config ihre Endpunkte hatte wie:

 https://myserver/myservice.svc 

aber das Zertifikat erwartete

 https://myserver.mydomain.com/myservice.svc

Das Ändern der Endpunkte entsprechend dem vollqualifizierten Domänennamen des Servers behebt mein Problem. Ich weiß, dass dies nicht die einzige Ursache für dieses Problem ist.

Mike Cheel
quelle
Ich hatte gerade dieses Problem wieder und dieses Mal musste es mit dem falschen Zertifikat verwendet werden. In beiden Fällen scheint es damit zu tun zu haben, dass Namen richtig abgeglichen werden.
Mike Cheel
3
In meiner automatisch generierten Konfiguration wurde dies durch < endpoint address = " localhost / myservice.svc " in < endpoint address = " mymachine.mydoman.com/myservice.svc " behoben.
Knightscharge
Dies war absolut mein Problem und ich habe zwei Tage gebraucht, um Ihre Antwort zu finden. +1, ich würde dir +1000 geben, wenn ich könnte.
AussieJoe
20

Die ersten beiden verwenden Lambda, die dritte verwendet regulären Code. Ich hoffe, Sie finden ihn hilfreich

            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);

            // trust sender
            System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

            // validate cert by calling a function
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

    // callback used to validate the certificate in an SSL conversation
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
    {
        bool result = false;
        if (cert.Subject.ToUpper().Contains("YourServerName"))
        {
            result = true;
        }

        return result;
    }
Sebastian Castaldi
quelle
1
// Allen Zertifikaten vertrauen System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return true; }; // Absender vertrauen System.Net.ServicePointManager.ServerCertificateValidationCallback + = (se, cert, chain, sslerror) => {return cert.Subject.Contains ("ca-l-9wfvrm1.ceridian.ca"); };
VoodooChild
1
Jeder Cracker könnte ein Zertifikat fälschen, das alle oben genannten Tests besteht. Das ist unsicher.
Bjartur Thorlacius
19

Ihr Problem tritt auf, weil Sie einen selbstsignierten Schlüssel verwenden. Der Client vertraut diesem Schlüssel weder, noch stellt der Schlüssel selbst eine zu validierende Kette oder eine Zertifikatsperrliste bereit.

Sie haben einige Möglichkeiten - Sie können

  1. Deaktivieren Sie die Zertifikatsüberprüfung auf dem Client (schlechter Zug, viele Angriffe in der Mitte gibt es zuhauf)

  2. Verwenden Sie makecert, um eine Stammzertifizierungsstelle zu erstellen und daraus Zertifikate zu erstellen (ok, verschieben, aber es gibt noch keine CRL).

  3. Erstellen Sie eine interne Stammzertifizierungsstelle mit Windows Certificate Server oder einer anderen PKI-Lösung und vertrauen Sie dann diesem Stammzertifikat (ein bisschen mühsam zu verwalten).

  4. Kauf eines SSL-Zertifikats von einer der vertrauenswürdigen Zertifizierungsstellen (teuer)

Blasrohrpfeil
quelle
3
In Bezug auf (4) erhalten Sie von StartSSL ein kostenloses Zertifikat der Klasse 1, das in allen gängigen Browsern funktioniert. Sie eignen sich hervorragend für ein halbes Dutzend Websites mit geringer Bandbreite.
Moodboom
Ich denke, Nummer 2 auf dieser Liste ... diese URL könnte helfen: blogs.technet.microsoft.com/jhoward/2005/02/02/… "Verwendung von MakeCert für vertrauenswürdige Stammzertifizierungsstellen und die Ausstellung von SSL-Zertifikaten"
granadaCoder
1
Hinweis: StartCom ist nicht mehr vertrauenswürdig - und wurde gerade aus Chrome en.wikipedia.org/wiki/StartCom entfernt
Simon_Weaver
16

Eine einzeilige Lösung. Fügen Sie dies an einer beliebigen Stelle hinzu, bevor Sie den Server auf der Clientseite aufrufen:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

Dies sollte nur zu Testzwecken verwendet werden, da der Client SSL / TLS-Sicherheitsüberprüfungen überspringt.

Gaspa79
quelle
2
Eine brillante Problemumgehung zum Testen. Wir verbrauchen einen Dienst, dessen Anbieter die Sicherheit mit einer verschlungenen Kette von Sicherheitszertifikaten zur Hölle gemacht hat, und bis wir ihre wackeligen Zertifikate und Verkettungen zum Funktionieren bringen können, ist diese Problemumgehung das einzige, was uns ermöglicht, die Entwicklung fortzusetzen.
Markaaronky
12

Ich bin auf dasselbe Problem gestoßen und konnte es mit zwei Lösungen beheben: Erstens habe ich das MMC-Snap-In "Zertifikate" für das "Computerkonto" verwendet und das selbstsignierte Zertifikat in den Ordner "Vertrauenswürdige Stammzertifizierungsstellen" gezogen . Dies bedeutet, dass der lokale Computer (derjenige, der das Zertifikat generiert hat) diesem Zertifikat jetzt vertraut. Zweitens habe ich festgestellt, dass das Zertifikat für einen internen Computernamen generiert wurde, aber auf den Webdienst unter einem anderen Namen zugegriffen wurde. Dies führte zu einer Nichtübereinstimmung bei der Validierung des Zertifikats. Wir haben das Zertifikat für computer.operations.local generiert, aber über https://computer.internaldomain.companydomain.com auf den Webdienst zugegriffen . Als wir die URL auf die URL umstellten, mit der das Zertifikat erstellt wurde, wurden keine Fehler mehr angezeigt.

Vielleicht hätte nur das Wechseln der URLs funktioniert, aber wenn Sie das Zertifikat als vertrauenswürdig einstufen, vermeiden Sie auch den roten Bildschirm in Internet Explorer, auf dem angegeben wird, dass das Zertifikat nicht vertrauenswürdig ist.

Jeroen-Bart Engelen
quelle
11

Wenn Sie .net Core verwenden, versuchen Sie Folgendes:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };
Grzegorz J.
quelle
1
Danke, es funktioniert. Aber es hat nichts mit .net Core zu tun. Es ist ein universelles Rezept :)
Alexander
7

Bitte führen Sie folgende Schritte aus:

  1. Öffnen Sie den Service-Link im IE.

  2. Klicken Sie auf den in der Adressleiste angegebenen Zertifikatfehler und dann auf Zertifikate anzeigen.

  3. Scheck ausgestellt an: Name.

  4. Nehmen Sie den ausgegebenen Namen und ersetzen Sie die Erwähnung von localhost im Dienst- und Client-Endpunkt-Basisadressnamen durch einen vollqualifizierten Domänennamen (FQDN).

Zum Beispiel: https: // localhost : 203 / SampleService.svc An https: // INL-126166-.groupinfra.com : 203 / SampleService.svc

Rahul Rai
quelle
Großartig, danke für diese Antwort! Die Probleme wurden behoben, ohne dass Codeänderungen vorgenommen wurden.
Vipin Dubey
6

Zusätzlich zu den obigen Antworten kann dieser Fehler auftreten, wenn auf Ihrem Client die falsche TLS-Version ausgeführt wird, z. B. wenn auf dem Server nur TLS 1.2 ausgeführt wird.

Sie können das Problem beheben, indem Sie Folgendes verwenden:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
NMrt
quelle
In meinem Fall hat mir die akzeptierte Antwort nicht geholfen, aber diese hat einen Trick gemacht
Sergey
Dies ist die einzige Antwort, die den Fehler in meinem Fall korrigiert hat.
Tolga
5

Ich hatte das gleiche Problem. Ich hatte auch CA-Zertifikate im lokalen Geschäft hinzugefügt, aber ich tat es auf die falsche Weise.

Mit der mmc-Konsole (Start -> Ausführen -> mmc ) sollten Sie das Zertifikat- Snap-In als Dienstkonto (Auswahl des Dienstkontos von IIS) oder Computerkonto (wird für jedes Konto auf dem Computer hinzugefügt) hinzufügen.

Hier ein Bild von dem, wovon ich spreche Fügen Sie ein Snap-In für ein Dienstkonto oder das Computerkonto hinzu

Von hier aus können Sie Zertifikate von Zertifizierungsstellen ( vertrauenswürdige Stammzertifizierungsstellen und Zwischenzertifizierungsstellen ) hinzufügen , und alles funktioniert einwandfrei

dar0x
quelle
4

Ich hatte ein ähnliches Problem mit dem selbstsignierten Zertifikat. Ich könnte es beheben, indem ich den Zertifikatsnamen verwende, der dem FQDN des Servers entspricht.

Idealerweise sollte der SSL-Teil auf der Serverseite verwaltet werden. Der Client muss kein Zertifikat für SSL installieren. In einigen der genannten Beiträge wurde auch die Umgehung von SSL aus dem Clientcode erwähnt. Aber damit bin ich überhaupt nicht einverstanden.

Umesh Bhavsar
quelle
3

Ich habe das Zertifikat einfach in den Ordner "Trusted Root Certification Authorities" gezogen und voila alles hat gut funktioniert.

Oh. Und ich habe zuerst Folgendes über eine Administrator-Eingabeaufforderung hinzugefügt:

netsh http add urlacl url=https://+:8732/Servicename user=NT-MYNDIGHET\INTERAKTIV

Ich bin mir nicht sicher, welchen Namen Sie für den Benutzer benötigen (meiner ist norwegisch, wie Sie sehen können!) : user=NT-AUTHORITY/INTERACTIVE?

Sie können alle vorhandenen URLs anzeigen, indem Sie den folgenden Befehl eingeben: netsh http show urlacl

Haguna
quelle
0

Dies trat auf, wenn versucht wurde, eine Verbindung zum WCF-Dienst über herzustellen. die IP zB https://111.11.111.1:port/MyService.svcbei Verwendung eines Zertifikats, das an einen Namen gebunden ist, zB mysite.com.

Wechsel zum https://mysite.com:port/MyService.svcgelösten Problem.

lko
quelle
0

Habe gerade ein ähnliches Problem behoben.

Mir wurde klar, dass ich einen Anwendungspool hatte, der unter einem Konto ausgeführt wurde, das nur Leseberechtigung für das verwendete Zertifikat hatte.

Die .NET-Anwendung konnte das Zertifikat korrekt abrufen, diese Ausnahme wurde jedoch nur beim Aufruf von GetRequestStream () ausgelöst.

Zertifikatsberechtigungen können über die MMC-Konsole verwaltet werden

Alberto
quelle
0

Wenn Sie den .net-Kern verwenden, können Sie während der Entwicklung die Zertifikatsüberprüfung mithilfe von Compiler-Anweisungen umgehen. Auf diese Weise wird das Zertifikat nur für die Freigabe und nicht für das Debuggen validiert:

#if (DEBUG)
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
                };   #endif
Panayiotis Hiripis
quelle
-6

Fügen Sie dies Ihrem Client-Code hinzu:

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });
user662285
quelle
4
Diese Antwort ist nicht sehr gut, da sie die mit dem Code verbundenen Risiken nicht erklärt.
Dave