Подтвердить что ты не робот

Как игнорировать ошибку сертификата с помощью С# 2.0 WebClient - без сертификата

Использование Visual Studio 2005 - С# 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 validation!, который kinda-sorta описывает мою проблему - кроме этого также sorta-sorta не потому, что я не знать, какой сертификат (если есть) я должен ссылаться.

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

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

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

4b9b3361

Ответ 1

Сертификат 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);
    }
}

Ответ 2

Я понимаю, что это старый пост, но я просто хотел показать, что есть более короткий способ сделать это (с .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;
        });

Ответ 3

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

Ответ 4

Это код, который мы используем (еще не отполированный - я не думаю, что правильно настроил обработку ошибок, но он должен быть близок) на основе предложения thomas (это, однако, код .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;
    }
}

Ответ 5

Я хотел отключить проверку 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;
        }

Ответ 6

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

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