C # Ignora gli errori del certificato?


159

Ricevo il seguente errore durante una richiesta di servizio Web a un servizio Web remoto:

Impossibile stabilire una relazione di fiducia per il canale sicuro SSL / TLS. ---> System.Security.Authentication.AuthenticationException: il certificato remoto non è valido secondo la procedura di convalida.

Esiste un modo per ignorare questo errore e continuare?

Sembra che il certificato remoto non sia firmato.

Il sito a cui mi collego è www.czebox.cz: non esitare a visitare il sito e nota che anche i browser generano eccezioni di sicurezza.

Risposte:


341

Aggiungi un gestore di convalida certificato. La restituzione trueconsentirà di ignorare l'errore di convalida:

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

6
Questo è ancora più utile di quanto possa sembrare a prima vista. Mi sono imbattuto nel problema del PO durante l'utilizzo di Managed Exchanged Web Services (EWS). Pensavo di non poter usare questa risposta poiché non avevo accesso alle chiamate SOAP di basso livello che venivano fatte da quella libreria gestita. Ma quando ho dato un'altra occhiata, mi sono reso conto che ServicePointManager è autonomo. Quindi, ho aggiunto il callback sopra prima di inizializzare ExchangeService e ha funzionato come un incantesimo.
Mark Meuer,

2
Ecco un esempio di come applicare il bypass a livello globale. Per tutti noi in cattive pratiche. (A volte non hai scelta) jasig.275507.n4.nabble.com/…
snowYetis

1
un grande grazie per risolvere temporaneamente il problema. Aggiungi questo codice in Startup.cs in Web Api
Sivalingaamorthy il

2
@MarkMeuer avrebbe quasi rinunciato a questa soluzione per il mio problema API EWS, ma poi ho visto il tuo commento.
Mahen,

7
@MiguelVeloso sei libero di esprimere il tuo voto, ma tieni presente che né la domanda né la risposta ne discutono sul lato della sicurezza. L'argomento è esplicitamente "come ignorare l'errore di convalida", non "perché dovremmo farlo / non farlo", che è un argomento completamente diverso. Andando in una discussione sul perché il PO non dovrebbe fare sarebbe solo confondere le acque, come commentatori hanno fatto notare ci sono casi in cui è effettivamente ragionevoli dovrebbe fare questo. Quindi atteniamo all'argomento e risolviamo il problema.
Peter Lillevold,

40

Consentire tutti i certificati è molto potente ma potrebbe anche essere pericoloso. Se si desidera consentire solo certificati validi oltre ad alcuni certificati, è possibile farlo in questo modo.

.Net core:

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;
};

Aggiornare:

Come ottenere cert.GetCertHashString()valore in Chrome:

Fai clic su Secureo Not Securenella barra degli indirizzi.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Quindi fare clic su Certificato -> Dettagli -> Identificazione personale e copiare il valore. Ricordati di fare cert.GetCertHashString().ToLower().

inserisci qui la descrizione dell'immagine


3
@MiguelVeloso Completamente d'accordo. Ciò consente di saltare il controllo (si spera) di uno o due certificati senza compromettere completamente la sicurezza.
Kemuel Sanchez,

Come posso ottenere Hash Stringda un certificato?
Kiquenet,

@Kiquenet O eseguire il debug del codice ed eseguire cert.GetCertHashString()da Immediate windowo assegno cert Thumbprintnel tuo browser o MMCse si è installato in locale.
Ogglas,

Il server è sotto il nostro controllo, è ancora sicuro usare il codice @ Ogglas in produzione? Utilizzando TLS / SSL, è possibile fermare un attacco come l'uomo in mezzo?
Pingpong,

Grazie di grande aiuto.
Wowo Ot,

30

Metodo IgnoreBadCertificates:

//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;
} 

2
Ho dovuto aggiungere un'altra riga per farlo funzionare con il mio codice (sto usando websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Subito dopo aver impostato il callback di convalida del certificato del server.
kalyanswaroop,

24

Il motivo per cui non riesce non è perché non è firmato ma perché il certificato radice non è considerato attendibile dal client. Anziché disattivare la convalida SSL, un approccio alternativo sarebbe quello di aggiungere il certificato CA radice all'elenco di CA attendibili dall'app.

Questo è il certificato della CA principale di cui l'app attualmente non si fida:

-----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-----

È possibile decodificare e visualizzare questo certificato utilizzando

questo decodificatore del certificato o un altro decodificatore del certificato


Sì! Questo è il mio caso, ma come posso aggiungere il certificato in Azure, senza una macchina virtuale? Posso semplicemente usare l'API X509Store? Lo proverò domani, ma qualsiasi informazione è benvenuta qui
João Antunes,

7

Per disabilitare la convalida del certificato SSL nella configurazione del client.

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>

Questo è web.config ? Qualche alternativa per ASP.NET Core?
Shimmy Weitzhandler,

5

Questo codice ha funzionato per me. Ho dovuto aggiungere TLS2 perché è quello che stava usando l'URL che mi interessa.

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);
}

3

Bypass certificato SSL ....

        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)

2

Se si utilizzano direttamente i socket e si esegue l'autenticazione come client, il metodo di callback di Service Point Manager non funzionerà. Ecco cosa ha funzionato per me. SI PREGA DI UTILIZZARE SOLO PER SCOPI DI PROVA .

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

La chiave qui è fornire il callback di convalida del certificato remoto proprio nel costruttore del flusso SSL.


1

Per espandere ulteriormente il post di BIGNUM - Idealmente, vuoi una soluzione che simuli le condizioni che vedrai in produzione e la modifica del codice non lo farà e potrebbe essere pericoloso se dimentichi di estrarre il codice prima di distribuirlo.

Avrai bisogno di un certificato autofirmato di qualche tipo. Se sai cosa stai facendo puoi usare il binario BIGNUM pubblicato, ma in caso contrario puoi andare a caccia del certificato. Se stai usando IIS Express ne avrai già uno, dovrai solo trovarlo. Apri Firefox o il browser che preferisci e vai al tuo sito Web di sviluppo. Dovresti essere in grado di visualizzare le informazioni sul certificato dalla barra degli URL e, a seconda del tuo browser, dovresti essere in grado di esportare il certificato in un file.

Quindi, aprire MMC.exe e aggiungere lo snap-in Certificato. Importa il tuo file di certificato nell'archivio delle autorità di certificazione radice attendibili e questo è tutto ciò di cui hai bisogno. È importante assicurarsi che vada in quel negozio e non in altri negozi come "Personale". Se non hai familiarità con MMC o certificati, ci sono numerosi siti Web con informazioni su come farlo.

Ora, il tuo computer nel suo insieme si fiderà implicitamente di tutti i certificati che ha generato se stesso e non dovrai aggiungere codice per gestirlo in modo speciale. Quando si passa alla produzione continuerà a funzionare purché sia ​​installato un certificato valido adeguato. Non farlo su un server di produzione - sarebbe un male e non funzionerebbe per altri client diversi da quelli sul server stesso.


1

Questo funziona per .Net Core. Chiama il tuo client Soap:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.