Запрос был прерван: не удалось создать безопасный канал SSL / TLS - PullRequest
302 голосов
/ 18 мая 2010

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

The request was aborted: Could not create SSL/TLS secure channel.

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

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

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

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


Я должен упомянуть, что мы с коллегой провели тесты несколько недель назад, и они работали нормально с чем-то похожим на то, что я написал выше. Единственное «основное отличие», которое мы обнаружили, заключается в том, что я использую Windows 7, а он - Windows XP. Это что-то меняет?

Ответы [ 36 ]

436 голосов
/ 25 мая 2010

Я наконец нашел ответ (я не указал свой источник, но он был от поиска);

Пока код работает в Windows XP, в Windows 7 вы должны добавить это в начале:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons

А теперь работает отлично.


ДОПОЛНЕНИЕ

Как упомянул Робин Френч; если вы столкнулись с этой проблемой при настройке PayPal, обратите внимание, что они не будут поддерживать SSL3 начиная с 3 декабря 2018 года. Вам нужно будет использовать TLS. Вот Страница PayPal об этом.

92 голосов
/ 22 февраля 2018

Решение этой проблемы в .NET 4.5 -

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

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

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
59 голосов
/ 22 июня 2018

Убедитесь, что настройки 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;
31 голосов
/ 18 мая 2010

Проблема в том, что у пользователя aspNet нет доступа к сертификату. Вы должны дать доступ, используя winhttpcertcfg.exe

Пример того, как это настроить: http://support.microsoft.com/kb/901183

В шаге 2 для получения дополнительной информации

РЕДАКТИРОВАТЬ: в более поздних версиях IIS эта функция встроена в инструмент диспетчера сертификатов - и получить доступ к ней можно, щелкнув правой кнопкой мыши по сертификату и используя опцию для управления закрытыми ключами. Подробнее здесь: https://serverfault.com/questions/131046/how-to-grant-iis-7-5-access-to-a-certificate-in-certificate-store/132791#132791

25 голосов
/ 18 мая 2010

Ошибка является общей, и существует множество причин, по которым согласование SSL / TLS может завершиться неудачей. Наиболее распространенным является недействительный или просроченный сертификат сервера, и вы позаботились об этом, предоставив свой собственный инструмент проверки сертификата сервера, но это не обязательно является единственной причиной. Сервер может требовать взаимной аутентификации, он может быть сконфигурирован с набором шифров, не поддерживаемых вашим клиентом, он может иметь слишком большой временной сдвиг для успешного установления связи и многие другие причины

Лучшее решение - использовать набор инструментов для устранения неполадок SChannel. SChannel - поставщик SSPI, отвечающий за SSL и TLS, и ваш клиент будет использовать его для рукопожатия. Взгляните на Инструменты и настройки TLS / SSL .

Также см. Как включить ведение журнала событий Schannel .

24 голосов
/ 15 октября 2014

У меня была эта проблема, когда я пытался нажать 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");
17 голосов
/ 04 декабря 2014

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

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

14 голосов
/ 01 июня 2016

Что-то, чего не было в первоначальном ответе. Я добавил еще немного кода, чтобы сделать его пуленепробиваемым.

ServicePointManager.Expect100Continue = true;
        ServicePointManager.DefaultConnectionLimit = 9999;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
13 голосов
/ 12 июля 2012

Другая возможность - неправильный ввоз сертификата на коробку. Обязательно установите флажок в кружке. Первоначально я этого не делал, поэтому код либо прерывался, либо выдавал то же исключение, поскольку закрытый ключ не мог быть найден.

certificate importation dialog

9 голосов
/ 19 августа 2014

Исключение «Запрос был прерван: не удалось создать безопасный канал SSL / TLS», если сервер возвращает HTTP 401 неавторизованный ответ на запрос HTTP.

Вы можете определить, происходит ли это, включив ведение журнала System.Net уровня трассировки для своего клиентского приложения, как описано в этот ответ .

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

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.

В моей ситуации мне не удалось установить определенный файл cookie, который ожидал сервер, что привело к тому, что сервер ответил на запрос с ошибкой 401, что, в свою очередь, привело к «Не удалось создать безопасный канал SSL / TLS» исключение.

...