Как игнорировать ошибку сертификата с помощью С# 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 не потому, что я не знать, какой сертификат (если есть) я должен ссылаться.
Есть ли способ игнорировать ошибку, не зная/не заботясь о том, какой сертификат вызывает проблему?
-
и, пожалуйста, - детские перчатки, маленькие слова и код "для чайников", поскольку я не совсем тяжелый нападающий.
-
Этот трафик проходит через личную линию, поэтому я понимаю, что игнорирование ошибки сертификата не так важно, как если бы это был открытый интернет-трафик.
Ответы
Ответ 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)