C # Ignorer les erreurs de certificat?

159

J'obtiens l'erreur suivante lors d'une demande de service Web à un service Web distant:

Impossible d'établir une relation d'approbation pour le canal sécurisé SSL / TLS. ---> System.Security.Authentication.AuthenticationException: le certificat distant n'est pas valide selon la procédure de validation.

Est-il possible d'ignorer cette erreur et de continuer?

Il semble que le certificat distant n'est pas signé.

Le site auquel je me connecte est www.czebox.cz- alors n'hésitez pas à visiter le site et notez que même les navigateurs lancent des exceptions de sécurité.

JL.
la source

Réponses:

341

Ajoutez un gestionnaire de validation de certificat. Le retour truepermettra d'ignorer l'erreur de validation:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;
Peter Lillevold
la source
6
C'est encore plus utile qu'il n'y paraît à première vue. J'ai rencontré le problème du PO en utilisant les services Web échangés gérés (EWS). Je pensais que je ne pouvais pas utiliser cette réponse car je n'avais pas accès aux appels SOAP de bas niveau qui étaient effectués par cette bibliothèque gérée. Mais quand j'y ai jeté un autre regard, j'ai réalisé que ServicePointManager était autonome. Donc, j'ai ajouté le rappel ci-dessus avant d'initialiser ExchangeService et cela a fonctionné comme un charme.
Mark Meuer
2
Voici un exemple d'application globale du contournement. Pour nous tous dans les mauvaises pratiques. (Parfois, vous n'avez pas le choix) jasig.275507.n4.nabble.com/…
snowYetis
1
un grand merci cela résout temporairement le problème. Ajoutez ce code dans Startup.cs dans Web Api
Sivalingaamorthy
2
@MarkMeuer allait presque abandonner cette solution pour mon problème d'API EWS, mais j'ai vu votre commentaire.
Mahen
7
@MiguelVeloso, vous êtes bien sûr libre de voter contre, mais gardez à l'esprit que ni la question ni la réponse ne discutent du côté de la sécurité. Le sujet est explicitement «comment ignorer l'erreur de validation», et non «pourquoi devrions-nous faire / ne pas faire cela», qui est un sujet complètement différent. Entrer dans une discussion sur les raisons pour lesquelles le PO ne devrait pas le faire ne ferait que brouiller les choses, comme les commentateurs l'ont souligné, il existe des cas raisonnables où vous feriez cela. Nous nous en tenons donc au sujet et résolvons le problème.
Peter Lillevold
40

Autoriser tous les certificats est très puissant, mais cela peut aussi être dangereux. Si vous souhaitez n'autoriser que des certificats valides plus certains certificats, cela pourrait être fait comme ceci.

Noyau .Net:

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

Framework .Net:

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

Mettre à jour:

Comment obtenir de la cert.GetCertHashString()valeur dans Chrome:

Cliquez sur Secureou Not Securedans la barre d'adresse.

entrez la description de l'image ici

entrez la description de l'image ici

Cliquez ensuite sur Certificat -> Détails -> Empreinte numérique et copiez la valeur. N'oubliez pas de faire cert.GetCertHashString().ToLower().

entrez la description de l'image ici

Ogglas
la source
3
@MiguelVeloso Tout à fait d'accord. Cela permet d'ignorer la vérification (espérons-le) d'un ou deux certificats sans compromettre complètement la sécurité.
Kemuel Sanchez
Comment puis-je obtenir Hash Stringun certificat?
Kiquenet
@Kiquenet Déboguez le code et exécutez-le cert.GetCertHashString()depuis Immediate windowou vérifiez cert Thumbprintdans votre navigateur ou MMCs'il est installé localement.
Ogglas
Le serveur est sous notre contrôle, est-il toujours sûr d'utiliser le code de @ Ogglas en production? En utilisant TLS / SSL, peut-on arrêter une attaque de type man-in-the-middle?
Pingpong le
Merci beaucoup d'aide.
Wowo Ot
30

IgnoreBadCertificates, méthode:

//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
la source
2
J'ai dû ajouter une ligne de plus pour que cela fonctionne avec mon code (j'utilise websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Juste après avoir défini le rappel de validation du certificat du serveur.
kalyanswaroop le
24

La raison pour laquelle il échoue n'est pas parce qu'il n'est pas signé, mais parce que le certificat racine n'est pas approuvé par votre client. Plutôt que de désactiver la validation SSL, une autre approche consiste à ajouter le certificat d'autorité de certification racine à la liste des autorités de certification approuvées par votre application.

Il s'agit du certificat d'autorité de certification racine auquel votre application ne fait actuellement pas confiance:

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

Vous pouvez décoder et afficher ce certificat en utilisant

ce décodeur de certificat ou un autre décodeur de certificat

bignum
la source
Oui! C'est mon cas, mais comment puis-je ajouter le certificat sur Azure, sans machine virtuelle? Puis-je simplement utiliser l'API X509Store? Je vais essayer ça demain mais toute information est la bienvenue ici
João Antunes
7

Pour désactiver la validation du certificat SSL dans la configuration du client.

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>
d.marzo
la source
S'agit-il de web.config ? Des alternatives pour ASP.NET Core?
Shimmy Weitzhandler
5

Ce code a fonctionné pour moi. J'ai dû ajouter TLS2 car c'est ce que l'URL qui m'intéresse utilisait.

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
la source
3

Contourner le certificat 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)
Rohit Jangid
la source
2

Si vous utilisez des sockets directement et que vous vous authentifiez en tant que client, la méthode de rappel Service Point Manager ne fonctionnera pas. Voici ce qui a fonctionné pour moi. VEUILLEZ UTILISER UNIQUEMENT À DES FINS DE TEST .

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

La clé ici, est de fournir le rappel de validation de certificat à distance directement dans le constructeur du flux SSL.

Mario
la source
1

Pour développer davantage l'article de BIGNUM - Idéalement, vous voulez une solution qui simulera les conditions que vous verrez en production et la modification de votre code ne le fera pas et pourrait être dangereuse si vous oubliez de retirer le code avant de le déployer.

Vous aurez besoin d'une sorte de certificat auto-signé. Si vous savez ce que vous faites, vous pouvez utiliser le binaire BIGNUM affiché, mais sinon vous pouvez aller chercher le certificat. Si vous utilisez IIS Express, vous en aurez déjà un, il vous suffira de le trouver. Ouvrez Firefox ou le navigateur de votre choix et accédez à votre site Web de développement. Vous devriez pouvoir afficher les informations du certificat à partir de la barre d'URL et en fonction de votre navigateur, vous devriez pouvoir exporter le certificat dans un fichier.

Ensuite, ouvrez MMC.exe et ajoutez le composant logiciel enfichable Certificat. Importez votre fichier de certificat dans le magasin des autorités de certification racines de confiance et c'est tout ce dont vous avez besoin. Il est important de s'assurer qu'il entre dans ce magasin et non dans un autre magasin comme «Personnel». Si vous ne connaissez pas MMC ou les certificats, il existe de nombreux sites Web contenant des informations sur la manière de procéder.

Maintenant, votre ordinateur dans son ensemble fera implicitement confiance à tous les certificats qu'il a générés lui-même et vous n'aurez pas besoin d'ajouter de code pour gérer cela spécialement. Lorsque vous passez à la production, il continuera de fonctionner à condition qu'un certificat valide approprié y soit installé. Ne faites pas cela sur un serveur de production - ce serait mauvais et cela ne fonctionnera pas pour d'autres clients que ceux du serveur lui-même.

Nigel Thomas
la source
1

Cela fonctionne pour .Net Core. Faites appel à votre client Soap:

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