Cómo ignorar un error de certificado con c # 2.0 WebClient - sin el certificado


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

Así que aquí hay una versión simplificada del código:

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
}

Este es el error que obtengo:

La conexión subyacente se cerró: no se pudo establecer una relación de confianza para el canal seguro SSL/TLS.

No tengo mucho control para ver lo que está sucediendo cuando sale la solicitud. Me dicen que está llegando al destino correcto y hay un "error de certificado". Esto es supuestamente porque hay un desajuste literal entre la dirección IP en mi solicitud y la URL a la que se resuelve. Tengo más de una IP a la que se supone que debo ir todos contra todos, por lo que especificar la URL no funcionará. No estoy adjuntando un certificado, ni se supone que lo haga de acuerdo con los propietarios del endpoint. Por "ellos" el error de certificado es 'normal y se supone que debo ignorarlo.

El cert en cuestión es supuestamente uno de los muchos certs de verisign que está "solo allí" en nuestro servidor. El los ejemplos que he visto para ignorar errores de cert parecen implicar que el solicitante está adjuntando un certificado x509 específico (que no lo soy).

He revisado . net WebService, omitir la validación ssl! que un poco-sorta describe mi problema - excepto que también un poco-sorta no lo hace porque no sé a qué certificado (si lo hay) debería hacer referencia.

¿Hay una manera para mí de ignorar el error sin realmente saber / cuidar qué certificado está causando la problema?

  • Y por favor, guantes de seda, palabras pequeñas y código "para tontos", ya que no soy exactamente un bateador pesado.

  • Este tráfico es a través de una línea privada, por lo que entiendo que ignorar el error cert no es tan importante como si fuera tráfico de Internet abierto.

Author: Community, 2009-08-19

6 answers

El certificado SSL es para que una máquina establezca una relación de confianza. Si escribe una dirección IP y termina hablando con otra, eso suena igual que un error de seguridad de secuestro de DNS, el tipo de cosa que SSL pretende ayudarlo a evitar, y tal vez algo que no desea tolerar de "ellos".

Si puede terminar hablando con más de una máquina (lo ideal sería que la hicieran aparecer como una para usted), necesitará un certificado para cada una de las máquinas posibles para iniciar confianza.

Para ignorar la confianza (solo he tenido que hacer esto temporalmente en escenarios de desarrollo) el siguiente fragmento puede funcionar para usted, pero le recomiendo encarecidamente que considere el impacto de ignorar la confianza antes de usarlo:

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);
    }
}
 51
Author: MattH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-08 17:18:25

Me doy cuenta de que este es un post antiguo, pero solo quería mostrar que hay una forma más corta de hacer esto (con.NET 3.5+ y posteriores).

Tal vez sea solo mi TOC, pero quería minimizar este código tanto como fuera posible. Esta parece ser la forma más corta de hacerlo, pero también he enumerado algunos equivalentes más largos a continuación:

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

El camino más corto en. NET 2.0 (que es sobre lo que se preguntaba específicamente la pregunta)

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

Es desafortunado que el camino lambda requiera usted para definir los parámetros, de lo contrario podría ser aún más corto.

Y en caso de que necesite un camino mucho más largo, aquí hay algunas alternativas adicionales:

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;
        });
 9
Author: Adam Plocher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-26 01:37:27

Este código es mucho más amplio de lo que cabría esperar. Se trata de todo el proceso. El proceso puede ser el exe, IIS en esta máquina, o incluso DLLHost.exe. Después de llamarlo, tenga un bloque finally que restaura las cosas a la normalidad eliminando el delegado que siempre devuelve true.

 7
Author: thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-25 20:05:22

Este es un poco el código que estamos usando (no pulido todavía - no creo que tenga la configuración de manejo de errores correctamente, pero debería estar cerca) basado en la sugerencia de Thomas (este es el código. NET 4.0, sin embargo):

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;
    }
}
 7
Author: Jaxidian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-08 20:23:58

Quería deshabilitar la verificación SSL para un dominio específico sin desactivarlo globalmente porque podría haber otras solicitudes en ejecución que no deberían verse afectadas, así que se me ocurrió esta solución (tenga en cuenta que uri es una variable dentro de una clase:

        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
Author: Jürgen Steinblock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-06 15:29:23

Aquí está el VB.net código para hacer que WebClient ignore el certificado SSL.

Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
 1
Author: MichaelDarkBlue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-14 19:06:23