Как игнорировать ошибку сертификата с c # 2.0 WebClient - без сертификата - PullRequest
32 голосов
/ 19 августа 2009

Использование Visual Studio 2005 - C # 2.0, System.Net.WebClient.UploadData(Uri address, byte[] data) Windows Server 2003

Итак, вот урезанная версия кода:

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
}

Это ошибка, которую я получаю:

Базовое соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL / TLS.

У меня нет большого контроля, чтобы видеть, что происходит, когда запрос исчезает. Мне сказали, что он достигает правильного места назначения и есть «ошибка сертификата». Предположительно это связано с тем, что в моем запросе есть буквальное несоответствие между IP-адресом и URL-адресом, к которому он относится. У меня есть несколько IP-адресов, которые я должен округлить, поэтому указание URL не будет работать. Я не прилагаю сертификат - и я не должен в соответствии с владельцами конечных точек. По их мнению, ошибка сертификата 'нормальная, и я должен ее игнорировать.

Сертификат, о котором идет речь, предположительно является одним из многих сертификатов verisign, который «только что существует» на нашем сервере. Все примеры, которые я видел для игнорирования ошибок сертификатов, все подразумевают, что запросчик прикрепляет определенный сертификат x509 (а я нет).

Я просмотрел .net WebService, обойти проверку ssl! Какая разновидность типа sorta описывает мою проблему - кроме того, что вроде своего рода sorta нет, потому что я не знаю, какой сертификат (если есть) я следует ссылаться.

Могу ли я игнорировать ошибку, не зная / не заботясь о том, какой сертификат вызывает проблему?

  • и, пожалуйста, - детские перчатки, маленькие слова и код "для чайников", так как я не совсем сильный нападающий.

  • Этот трафик идет по частной линии - поэтому я понимаю, что игнорирование ошибки сертификата не так уж важно, как если бы это был открытый интернет-трафик.

Ответы [ 6 ]

54 голосов
/ 19 августа 2009

SSL-сертификат предназначен для машины, которая устанавливает доверительные отношения. Если вы вводите один IP-адрес и в конечном итоге разговариваете с другим, это звучит так же, как ошибка безопасности DNS-перехвата, то, что SSL намеревается помочь вам избежать - и, возможно, что-то, с чем вы не хотите мириться от "них".

Если вы в конечном итоге поговорите с чем-то большим, чем с машиной (в идеале они сделают так, чтобы он выглядел как один для вас), вам понадобится сертификат для каждой из возможных машин, чтобы инициировать доверие.

Чтобы игнорировать доверие (мне когда-либо приходилось делать это временно в сценариях разработки), следующий фрагмент может работать для вас, но я настоятельно рекомендую вам рассмотреть влияние игнорирования доверия перед его использованием:

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);
    }
}
10 голосов
/ 26 июня 2014

Я понимаю, что это старый пост, но я просто хотел показать, что есть более короткий способ сделать это (с .NET 3.5+ и более поздними версиями).

Может быть, это просто мой OCD, но я хотел максимально сократить этот код. Это, кажется, самый короткий способ сделать это, но я также перечислил несколько более длинных эквивалентов ниже:

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

Кратчайший путь в .NET 2.0 (именно об этом конкретно спрашивался вопрос)

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

К сожалению, лямбда-путь требует от вас определения параметров, иначе он может быть еще короче.

А если вам нужен гораздо более длинный путь, вот несколько дополнительных альтернатив:

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;
        });
8 голосов
/ 09 июля 2011

Это некоторый код, который мы используем (еще не отточенный - я не думаю, что у меня правильно настроена обработка ошибок, но она должна быть близка), основываясь на предложении Томаса (хотя это код .NET 4.0) :

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 голосов
/ 26 августа 2009

Этот код намного шире, чем вы могли ожидать. Это на весь процесс. Процесс может быть exe, IIS на этом компьютере или даже DLLHost.exe. После его вызова создайте блок finally, который восстанавливает нормальное состояние, удаляя делегат, который всегда возвращает true.

1 голос
/ 14 марта 2017

Вот код VB.net, чтобы WebClient игнорировал сертификат SSL.

Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
1 голос
/ 06 октября 2016

Я хотел отключить проверку SSL для определенного домена, не отключая его глобально, потому что могут быть запущены другие запросы, которые не должны быть затронуты, поэтому я пришел к этому решению (обратите внимание, что uri - это переменная внутри класса:

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