7

Запрос прерван: Не удалось создать безопасный канал SSL/TLS

10

Мы не можем подключиться к HTTPS серверу с использованием WebRequest из-за следующего сообщения об ошибке:

Запрос был прерван: Не удалось создать защищённый канал SSL/TLS.

Мы понимаем, что у сервера нет действительного HTTPS сертификата для указанного пути, но чтобы обойти эту проблему, мы используем следующий код, который нашли в одном из постов на StackOverflow:

private void Somewhere() {
    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AlwaysGoodCertificate);
}

private static bool AlwaysGoodCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) {
   return true;
}

Проблема в том, что сервер никогда не проверяет сертификат и выдает указанную выше ошибку. У кого-нибудь есть идеи, что мне делать?

5 ответ(ов)

9

В более современных средах, которые поддерживают или требуют более новые версии SSL (TLS), вам нужно добавить следующий код перед выполнением HTTP-запроса:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Используйте SecurityProtocolType.Ssl3, если это необходимо для обеспечения совместимости

Это гарантирует, что ваш код будет использовать TLS 1.2 для соединений, что является более безопасным вариантом по сравнению со старыми протоколами.

2

Решение этой проблемы в .NET 4.5 и выше заключается в следующем:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Если у вас версия .NET ниже 4.5, используйте:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
2

Убедитесь, что настройки ServicePointManager задаются до создания HttpWebRequest, иначе это не сработает.

Рабочий пример:

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
       | SecurityProtocolType.Tls11
       | SecurityProtocolType.Tls12
       | SecurityProtocolType.Ssl3;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/");

Пример с ошибкой:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/");

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
       | SecurityProtocolType.Tls11
       | SecurityProtocolType.Tls12
       | SecurityProtocolType.Ssl3;

В первом случае настройки применяются перед созданием запроса, что позволяет использовать указанные параметры безопасности. Во втором случае, когда настройки устанавливаются после создания запроса, они не будут применены, что приведет к ошибке.

0

У меня возникла проблема при попытке загрузить изображение по адресу https://ct.mob0.com/Styles/Fun.png, которое распределяется через CloudFlare на их CDN и поддерживает такие особенности, как SPDY и странные SSL-сертификаты для перенаправления.

Вместо того чтобы использовать Ssl3, как указано в ответе Симона, я смог решить проблему, снизив версию протокола до Tls12 следующим образом:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");

Это позволило успешно загрузить изображение. Надеюсь, этот способ поможет и вам!

0

После долгих часов борьбы с этой же проблемой, я обнаружил, что учетная запись ASP.NET, под которой работает клиентская служба, не имела доступа к сертификату. Я решил проблему, зайдя в пул приложений IIS, под которым работает веб-приложение, открыл "Расширенные настройки" и изменил Идентичность на учетную запись LocalSystem вместо NetworkService.

Лучшим решением будет настроить сертификат для работы с учетной записью по умолчанию NetworkService, но данный подход подойдет для быстрого функционального тестирования.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь