C # Zertifikatfehler ignorieren?

159

Während einer Webdienstanforderung an einen Remote-Webdienst wird folgende Fehlermeldung angezeigt:

Vertrauensbeziehung für den sicheren SSL / TLS-Kanal konnte nicht hergestellt werden. ---> System.Security.Authentication.AuthenticationException: Das Remote-Zertifikat ist gemäß dem Validierungsverfahren ungültig.

Gibt es eine Möglichkeit, diesen Fehler zu ignorieren und fortzufahren?

Es scheint, dass das Remote-Zertifikat nicht signiert ist.

Die Site, zu der ich eine Verbindung herstelle, ist www.czebox.cz- besuchen Sie die Site und beachten Sie, dass selbst Browser Sicherheitsausnahmen auslösen.

J L.
quelle

Antworten:

341

Fügen Sie einen Handler für die Zertifikatsüberprüfung hinzu. Bei der Rückgabe truekann der Validierungsfehler ignoriert werden:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;
Peter Lillevold
quelle
6
Dies ist noch nützlicher, als es auf den ersten Blick erscheinen mag. Bei der Verwendung von EWS (Managed Exchanged Web Services) bin ich auf das Problem des OP gestoßen. Ich dachte, dass ich diese Antwort nicht verwenden könnte, da ich keinen Zugriff auf die SOAP-Aufrufe auf niedriger Ebene hatte, die von dieser verwalteten Bibliothek getätigt wurden. Aber als ich es mir noch einmal ansah, stellte ich fest, dass ServicePointManager für sich allein steht. Also habe ich den obigen Rückruf hinzugefügt, bevor ich den ExchangeService initialisiert habe, und es hat wie ein Zauber funktioniert.
Mark Meuer
2
Hier ist ein Beispiel für die globale Anwendung des Bypasses. Für uns alle in schlechte Praktiken. (Manchmal haben Sie keine Wahl) jasig.275507.n4.nabble.com/…
snowYetis
1
Ein großes Dankeschön, das das Problem vorübergehend löst. Fügen Sie diesen Code in Startup.cs in Web Api
Sivalingaamorthy
2
@MarkMeuer würde diese Lösung für mein EWS-API-Problem fast aufgeben, aber dann habe ich Ihren Kommentar gesehen.
Mahen
7
@ MiguelVeloso Es steht Ihnen frei, natürlich abzustimmen, aber denken Sie daran, dass weder die Frage noch die Antwort die Sicherheitsseite davon diskutieren. Das Thema ist explizit "wie man den Validierungsfehler ignoriert", nicht "warum sollten wir dies tun / nicht tun", was insgesamt ein anderes Thema ist. Eine Diskussion darüber, warum das OP dies nicht tun sollte, würde nur das Wasser trüben, da Kommentatoren darauf hingewiesen haben, dass es vernünftige Fälle gibt, in denen Sie dies tatsächlich tun würden . Also bleiben wir beim Thema und lösen das Problem.
Peter Lillevold
40

Das Zulassen aller Zertifikate ist sehr leistungsfähig, kann aber auch gefährlich sein. Wenn Sie nur gültige Zertifikate und einige bestimmte Zertifikate zulassen möchten, können Sie dies folgendermaßen tun.

.Net-Kern:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };
    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

.Net Framework:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;   //Is valid
    }

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
    {
        return true;
    }

    return false;
};

Aktualisieren:

So erhalten Sie cert.GetCertHashString()Wert in Chrome:

Klicken Sie auf Secureoder Not Securein der Adressleiste.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Klicken Sie dann auf Zertifikat -> Details -> Fingerabdruck und kopieren Sie den Wert. Denken Sie daran cert.GetCertHashString().ToLower().

Geben Sie hier die Bildbeschreibung ein

Ogglas
quelle
3
@ MiguelVeloso Stimme voll und ganz zu. Dies ermöglicht das Überspringen der Überprüfung (hoffentlich) eines oder zweier Zertifikate, ohne die Sicherheit vollständig zu gefährden.
Kemuel Sanchez
Wie kann ich Hash Stringvon einem Zertifikat bekommen?
Kiquenet
@Kiquenet Debuggen Sie entweder den Code und führen Sie ihn cert.GetCertHashString()aus Immediate windowoder überprüfen Sie das Zertifikat Thumbprintin Ihrem Browser oder MMCob es lokal installiert ist.
Ogglas
Der Server ist in unserer Kontrolle. Ist es immer noch sicher, den Code von @ Ogglas in der Produktion zu verwenden? Kann mit TLS / SSL ein Angriff wie ein Mann in der Mitte gestoppt werden?
Pingpong
Vielen Dank, sehr große Hilfe.
Wowo Ot
30

IgnoreBadCertificates-Methode:

//I use a method to ignore bad certs caused by misc errors
IgnoreBadCertificates();

// after the Ignore call i can do what ever i want...
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest;

/*
and below the Methods we are using...
*/

/// <summary>
/// Together with the AcceptAllCertifications method right
/// below this causes to bypass errors caused by SLL-Errors.
/// </summary>
public static void IgnoreBadCertificates()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
}  

/// <summary>
/// In Short: the Method solves the Problem of broken Certificates.
/// Sometime when requesting Data and the sending Webserverconnection
/// is based on a SSL Connection, an Error is caused by Servers whoes
/// Certificate(s) have Errors. Like when the Cert is out of date
/// and much more... So at this point when calling the method,
/// this behaviour is prevented
/// </summary>
/// <param name="sender"></param>
/// <param name="certification"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns>true</returns>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
} 
Amen Ra
quelle
2
Ich musste eine weitere Zeile hinzufügen, damit dies mit meinem Code funktioniert (ich verwende websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Direkt nach dem Einstellen des Rückrufs zur Überprüfung der Serverzertifizierung.
kalyanswaroop
24

Der Grund dafür ist, dass es nicht signiert ist, sondern dass Ihr Client dem Stammzertifikat nicht vertraut. Anstatt die SSL-Validierung zu deaktivieren, besteht ein alternativer Ansatz darin, das Stammzertifizierungsstellenzertifikat zur Liste der Zertifizierungsstellen hinzuzufügen, denen Ihre App vertraut.

Dies ist das Stammzertifizierungsstellenzertifikat, dem Ihre App derzeit nicht vertraut:

-----BEGIN CERTIFICATE-----
MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs
MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc
BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y
NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf
2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT+tVDTeUUjT133G
7Vs51D6z/ShWy+9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH
0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2+X3hXBfvRMr5l6zgxYVATEyxCfOLM9
a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL
owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz
iWR+3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC+gLYYraHR0
cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs
aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv
oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww
gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50
byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw
b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp
cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk
aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp
b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw+r+
S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN
5OTjbpOTEEkq2jFI0tUhtRx//6zwuqJCzfO/KqggUrHBca+GV/qXcNzNAlytyM71
fMv/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK/m+IFfirxSRi8LRERdXHTEb
vwxMXIzZVXloWvX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a+y+z184UhuZ/oGyMw
eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF
Y+jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36+NyEK/ts3mPLL

-----END CERTIFICATE-----

Sie können dieses Zertifikat mit dekodieren und anzeigen

dieser Zertifikatsdecoder oder ein anderer Zertifikatsdecoder

Bignum
quelle
Ja! Dies ist mein Fall, aber wie kann ich das Zertifikat in Azure ohne VM hinzufügen? Kann ich einfach die X509Store-API verwenden? Ich werde das morgen versuchen, aber jede Info ist hier willkommen
João Antunes
7

So deaktivieren Sie die SSL-Zertifikatsüberprüfung in der Clientkonfiguration

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>
d.marzo
quelle
Ist das web.config ? Gibt es Alternativen für ASP.NET Core?
Shimmy Weitzhandler
5

Dieser Code hat bei mir funktioniert. Ich musste TLS2 hinzufügen, da die URL, an der ich interessiert bin, verwendet wurde.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, cert, chain, sslPolicyErrors) => { return true; };
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(UserDataUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new
      MediaTypeWithQualityHeaderValue("application/json"));
    Task<string> response = client.GetStringAsync(UserDataUrl);
    response.Wait();

    if (response.Exception != null)
    {
         return null;
    }

    return JsonConvert.DeserializeObject<UserData>(response.Result);
}
user2347528
quelle
3

SSL-Zertifikat umgehen ....

        HttpClientHandler clientHandler = new HttpClientHandler();
        clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

        // Pass the handler to httpclient(from you are calling api)
        var client = new HttpClient(clientHandler)
Rohit Jangid
quelle
2

Wenn Sie Sockets direkt verwenden und sich als Client authentifizieren, funktioniert die Service Point Manager-Rückrufmethode nicht. Folgendes hat bei mir funktioniert. BITTE NUR FÜR PRÜFZWECKE VERWENDEN .

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; });
await activeStream.AuthenticateAsClientAsync("computer.local");

Der Schlüssel hierbei ist, den Rückruf für die Remote-Zertifikatvalidierung direkt im Konstruktor des SSL-Streams bereitzustellen.

Mario
quelle
1

Um den Beitrag von BIGNUM weiter auszubauen - Idealerweise möchten Sie eine Lösung, die die Bedingungen simuliert, die Sie in der Produktion sehen, und das Ändern Ihres Codes funktioniert nicht und kann gefährlich sein, wenn Sie vergessen, den Code vor der Bereitstellung herauszunehmen.

Sie benötigen ein selbstsigniertes Zertifikat. Wenn Sie wissen, was Sie tun, können Sie die Binärdatei BIGNUM verwenden, aber wenn nicht, können Sie nach dem Zertifikat suchen. Wenn Sie IIS Express verwenden, haben Sie bereits eines davon, Sie müssen es nur finden. Öffnen Sie Firefox oder einen beliebigen Browser und rufen Sie Ihre Entwickler-Website auf. Sie sollten in der Lage sein, die Zertifikatinformationen in der URL-Leiste anzuzeigen und abhängig von Ihrem Browser das Zertifikat in eine Datei exportieren zu können.

Öffnen Sie als Nächstes MMC.exe und fügen Sie das Zertifikat-Snap-In hinzu. Importieren Sie Ihre Zertifikatdatei in den Speicher für vertrauenswürdige Stammzertifizierungsstellen, und das ist alles, was Sie benötigen sollten. Es ist wichtig sicherzustellen, dass es in dieses Geschäft geht und nicht in ein anderes Geschäft wie "Personal". Wenn Sie mit MMC oder Zertifikaten nicht vertraut sind, gibt es zahlreiche Websites mit Informationen dazu.

Jetzt vertraut Ihr Computer als Ganzes implizit allen Zertifikaten, die er selbst generiert hat, und Sie müssen keinen Code hinzufügen, um dies speziell zu handhaben. Wenn Sie zur Produktion wechseln, funktioniert es weiter, vorausgesetzt, Sie haben dort ein ordnungsgemäßes gültiges Zertifikat installiert. Tun Sie dies nicht auf einem Produktionsserver - das wäre schlecht und funktioniert nicht für andere Clients als die auf dem Server selbst.

Nigel Thomas
quelle
1

Dies funktioniert für .Net Core. Rufen Sie Ihren Soap-Client an:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
Rimi
quelle