web-dev-qa-db-fra.com

Comment ignorer une erreur de certificat avec c # 2.0 WebClient - sans le certificat

Utilisation de Visual Studio 2005 - C # 2.0, System.Net.WebClient.UploadData(Uri address, byte[] data) Windows Server 2003

Voici donc une version allégée du code:

static string SO_method(String fullRequestString)
{
    string theUriStringToUse = @"https://10.10.10.10:443"; // populated with real endpoint IP:port
    string proxyAddressAndPort = @"http://10.10.10.10:80/"; // populated with a real proxy IP:port
    Byte[] utf8EncodedResponse; // for the return data in utf8
    string responseString; // for the return data in utf16

    WebClient myWebClient = new WebClient(); // instantiate a web client
    WebProxy proxyObject = new WebProxy(proxyAddressAndPort, true);// instantiate & popuylate a web proxy
    myWebClient.Proxy = proxyObject; // add the proxy to the client
    myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // stick some stuff in the header

    UTF8Encoding utf8Encoding = new UTF8Encoding(false);// create a utf8 encoding
    Byte[] utf8EncodedRequest = HttpUtility.UrlEncodeToBytes(fullRequestString, utf8Encoding); // convert the request data to a utf8 byte array

    try
    {
        utf8EncodedResponse = myWebClient.UploadData(theUriStringToUse, "POST", utf8EncodedRequest); // pass the utf8-encoded byte array
        responseString = utf8Encoding.GetString(utf8EncodedResponse); // get a useable string out of the response
    }
    catch (Exception e)
    {
        // some other error handling
        responseString = "<CommError><![CDATA[" + e.ToString() + "]]></CommError>";// show the basics of the problem
    }
    return responseString;// return whatever ya got
}

Voici l'erreur que j'obtiens:

La connexion sous-jacente a été fermée: impossible d'établir une relation d'approbation pour le canal sécurisé SSL/TLS.

Je n'ai pas beaucoup de contrôle pour voir ce qui se passe lorsque la demande est envoyée. On me dit qu'il atteint la bonne destination et qu'il y a une "erreur de certificat". Ceci est supposé être dû au fait qu'il y a un décalage littéral entre l'adresse IP dans ma demande et l'URL vers laquelle elle se résout. J'ai plus d'une adresse IP à laquelle je suis censé faire un round-robin afin de spécifier l'URL ne fonctionnera pas. Je ne joins pas de certificat - et je ne suis pas censé le faire selon les propriétaires de terminaux. Pour "eux", l'erreur de certificat est "normale" et je suis censée l'ignorer.

Le certificat en question est censé être l'un des nombreux certificats verisign qui est "juste là" sur notre serveur. Les exemples que j'ai vus pour ignorer les erreurs de certificat semblent tous impliquer que le demandeur joint un certificat x509 spécifique (ce que je ne suis pas).

J'ai regardé par-dessus . Net WebService, contournez la validation SSL! quel type de sorta décrit mon problème - sauf qu'il ne le fait pas non plus parce que je ne sais pas quel certificat (le cas échéant) je dois référencer .

Existe-t-il un moyen pour moi d'ignorer l'erreur sans vraiment savoir/prendre soin du certificat qui cause le problème?

  • et s'il vous plaît - gants pour enfants, petits mots et code "pour les nuls" car je ne suis pas vraiment un gros frappeur.

  • Ce trafic est sur une ligne privée - donc je crois comprendre que l'ignorance de l'erreur de certificat n'est pas aussi grave que s'il s'agissait d'un trafic Internet ouvert.

33
JohnTheBarber

Le certificat SSL permet à une machine d'établir une relation de confiance. Si vous tapez une adresse IP et que vous finissez par en parler à une autre, cela ressemble à une faille de sécurité DNS Hijack, le genre de chose que SSL a l'intention de vous aider à éviter - et peut-être quelque chose que vous ne voulez pas accepter d'eux".

Si vous finissez par parler à plus d'une machine (idéalement, ils la feront apparaître comme une pour vous), vous aurez besoin d'un certificat pour chacune des machines possibles pour initier la confiance.

Pour ignorer la confiance (je n'ai dû le faire que temporairement dans les scénarios de développement), l'extrait de code suivant peut fonctionner pour vous, mais je vous recommande fortement de prendre en compte l'impact de l'ignorance de la confiance avant de l'utiliser:

public static void InitiateSSLTrust()
{
    try
    {
        //Change SSL checks so that all checks pass
        ServicePointManager.ServerCertificateValidationCallback =
           new RemoteCertificateValidationCallback(
                delegate
                { return true; }
            );
    }
    catch (Exception ex)
    {
        ActivityLog.InsertSyncActivity(ex);
    }
}
55
MattH

Je me rends compte que c'est un vieux post, mais je voulais juste montrer qu'il y a un moyen plus court de le faire (avec .NET 3.5+ et versions ultérieures).

C'est peut-être juste mon OCD, mais je voulais minimiser autant que possible ce code. Cela semble être le moyen le plus court de le faire, mais j'ai également énuméré quelques équivalents plus longs ci-dessous:

// 79 Characters (72 without spaces)
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;

Le plus court chemin dans .NET 2.0 (qui est ce que la question demandait spécifiquement)

// 84 Characters
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Il est regrettable que la méthode lambda vous oblige à définir les paramètres, sinon elle pourrait être encore plus courte.

Et si vous avez besoin d'un chemin beaucoup plus long, voici quelques alternatives supplémentaires:

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

ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; };

// 255 characters - lots of code!
ServicePointManager.ServerCertificateValidationCallback =
    new RemoteCertificateValidationCallback(
        delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        });
10
Adam Plocher

C'est un peu le code que nous utilisons (pas encore poli - je ne pense pas avoir correctement configuré la gestion des erreurs mais il devrait être proche) basé sur la suggestion de thomas (c'est du code .NET 4.0, cependant):

var sslFailureCallback = new RemoteCertificateValidationCallback(delegate { return true; });

try
{

    if (ignoreSslErrors)
    {
        ServicePointManager.ServerCertificateValidationCallback += sslFailureCallback;
    }

    response = webClient.UploadData(Options.Address, "POST", Encoding.ASCII.GetBytes(Options.PostData));

}
catch (Exception err)
{
    PageSource = "POST Failed:\r\n\r\n" + err;
    return PageSource;
}
finally
{
    if (ignoreSslErrors)
    {
        ServicePointManager.ServerCertificateValidationCallback -= sslFailureCallback;
    }
}
8
Jaxidian

Ce code est beaucoup plus large que vous ne le pensez. C'est à l'échelle du processus. Le processus peut être l'exe, IIS sur cette machine, ou même DLLHost.exe. Après l'avoir appelé, ayez un bloc finally qui restaure les choses à la normale en supprimant le délégué qui retourne toujours vrai.

8
thomas

Voici le code VB.net pour que WebClient ignore le certificat SSL.

Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
1
MichaelDarkBlue

Je voulais désactiver la vérification SSL pour un domaine spécifique sans la désactiver globalement car il pourrait y avoir d'autres demandes en cours d'exécution qui ne devraient pas être affectées, j'ai donc proposé cette solution (veuillez noter que uri est une variable à l'intérieur d'une classe:

        private byte[] UploadValues(string method, NameValueCollection data)
        {
            var client = new WebClient();

            try
            {
                ServicePointManager.ServerCertificateValidationCallback +=
                    ServerCertificateValidation;

                returnrclient.UploadValues(uri, method, parameters);

            }
            finally
            {
                ServicePointManager.ServerCertificateValidationCallback -=
                    ServerCertificateValidation;
            }
        }

        private bool ServerCertificateValidation(object sender,
            X509Certificate certificate, X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            var request = sender as HttpWebRequest;
            if (request != null && request.Address.Host.Equals(
                this.uri.Host, StringComparison.OrdinalIgnoreCase))
                return true;
            return false;
        }
1