Указание имени сервера из C #

Насколько я могу судить, похоже, что в .NET существует большое ограничение в том, что нет возможности использовать C # и .NET для создания TLS-соединения, использующего указание имени сервера (SNI). Я что-то пропустил или правильно понимаю?

Кто-нибудь знает, можно ли и как я могу установить соединение SNI с помощью OpenSSL.NET, libcurl.NET или какой-либо другой сторонней библиотеки .NET? Был бы очень признателен некоторый образец кода.


person woollybrain    schedule 14.11.2013    source источник
comment
Наш SecureBlackbox полностью поддерживает SNI как в клиентских, так и в серверных компонентах TLS.   -  person Eugene Mayevski 'Callback    schedule 14.11.2013
comment
Спасибо, проверю.   -  person woollybrain    schedule 14.11.2013
comment
SNI - это расширение TLS, а не SSL, поэтому первым шагом является выбор правильного протокола. Но да, .NET начиная с 4.5 не поддерживает SNI, что чертовски досадно. connect.microsoft.com/VisualStudio/feedback/details/729925/   -  person Bruno Rohée    schedule 21.11.2013
comment
@Bruno, спасибо. Я обновил вопрос, чтобы указать правильный протокол. Было бы проще, если бы IETF называл свою версию SSL v4 ;-)   -  person woollybrain    schedule 21.11.2013
comment
@ EugeneMayevski'EldoSCorp Есть ли документация (желательно образец кода) о том, как использовать ваш TElHTTPSClient класс с SNI? На этой странице перечислены только члены класса, но нет дополнительных указаний. Также не установлен образец проекта, который показал бы, как использовать HTTPS.   -  person Clemens    schedule 20.10.2014
comment
@Clemens См., Например, это сообщение на форуме: eldos.com/forum/ read.php? FID = 7 & TID = 5534   -  person Eugene Mayevski 'Callback    schedule 20.10.2014
comment
@ EugeneMayevski'EldoSCorp Спасибо за ссылку, но этот пост, похоже, о TElSMTPClient, а не о TElHTTPSClient.   -  person Clemens    schedule 20.10.2014
comment
@Clemens это не имеет значения - код тот же. Вы можете задавать дополнительные вопросы на нашем форуме и в службе поддержки - мы не предоставляем поддержку через StackOverflow.   -  person Eugene Mayevski 'Callback    schedule 20.10.2014


Ответы (2)


В моем проекте .Net 4.5 для сервера, использующего SNI, не работает следующее:

var url = "https://www.somesite.com";
System.Net.WebClient client = new System.Net.WebClient();
client.Encoding = Encoding.UTF8;
var data = client.DownloadString(url);

Но он работает, если явно указать TLS1.2, добавив к нему префикс:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

То же самое и с веб-запросом:

WebRequest request = WebRequest.Create("https://www.somesite.com");

и HttpRequestMessage:

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");

Всем им нужен протокол, явно настроенный на TLS 1.2 для работы с сервером SNI (это могло измениться в более новых версиях .Net)

person Tikall    schedule 28.06.2018
comment
Где именно вы используете префикс SecurityProtocolType.Tls12 с помощью WebClient? Txs! - person smoore4; 28.01.2019
comment
Видимо где угодно, как в этом вопросе? stackoverflow.com/ questions / 20064505 / - person smoore4; 28.01.2019

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

.NET Framework по умолчанию поддерживает указание имени сервера. (Проверено на 4.5.1, но я думаю, что то же самое, по крайней мере, для .NET 4.5+)

Краткий пример:

HttpResponseMessage response;
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");

var handler = new HttpClientHandler
{
    CookieContainer = new CookieContainer()
};
using (var client = new HttpClient(handler))
{
    response = client.SendAsync(httpRequestMessage).Result;
}

Это очень стандартный способ создания запроса GET в C #. Вы увидите, что этот пример работает, в моем случае, с использованием TLS 1.2 с SNI. Если вы используете Wireshark для просмотра фактических отправленных пакетов, вы увидите сообщение Client Hello с указанием имени сервера, установленным на www.google.com.

Проблема, с которой мы столкнулись: тег SNI устанавливается .NET Framework (или Schannel Windows, не уверен) на основе URL-адреса, переданного в конструкторе HttpRequestMessage. Если вы знаете, что инициализировать запрос на основе некоторого URL (например, https://www.google.com) и более поздних версий при переключении заголовка RequestUri ИЛИ Host тег SNI по-прежнему будет создан на основе исходного URL-адреса. Это может иметь место, например, если вы проходите через запрос и переназначаете все исходные заголовки на вновь созданный запрос.

person panick    schedule 26.09.2016
comment
Боюсь, я не могу воспроизвести поведение, которое вы упомянули в последнем абзаце (что прискорбно, поскольку я надеялся использовать это как хакерский способ изменения тега SNI). Я разместил это как дополнительный вопрос. - person fuglede; 14.01.2019