Ошибка аутентификации, поскольку удаленная сторона закрыла транспортный поток


87

Я разрабатываю TCP-клиент для подключения сервера OpenSSL с проверкой подлинности сертификата. Я использую файлы .crt и .key, общие для серверной команды. Эти сертификаты генерируются командами OpenSSL.

Я использую SslStreamобъект для аутентификации клиента Tcp, вызывая SslStream.AuthenticateAsClientметод, передавая сервер IP, SslProtocols.Ssl3и X509CertificateCollection.

Я получаю следующую ошибку:

Ошибка аутентификации, поскольку удаленная сторона закрыла транспортный поток


2
Это выглядит как проблема в посте-ПУДЕЛЕ дней: SslProtocols.Ssl3. Может тебе стоит попробовать SslProtocols.Tls. В .Net 4.5 и выше вы также можете использовать Tls11или Tls12. См. « Перечисление SslProtocols» . У вас могут быть другие проблемы.
jww 05


Спасибо. Моя проблема решена путем прикрепления сертификата к физическому пути сертификата и пароля вместо поиска имени субъекта сертификата из хранилища сертификатов Windows.
Odelu 08

Теперь я могу получить результат для всех протоколов Ssl (SSL3, Tls1 и Tls2). Спасибо за ответ,
Odelu 08

@Odelu, как ты решил проблему? На стороне клиента или на стороне сервера?

Ответы:


155

Я бы не советовал ограничивать SecurityProtocol до TLS 1.1.

Рекомендуемое решение - использовать

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

Другой вариант - добавить следующий ключ реестра:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

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


6
вау, вы только что разобрались с моей проблемой - я пробовал разные вещи - а потом я увидел заметку о фреймворке. Просто переключил его на 4.6.1 (использовал 4.5), надеясь, что проблема будет в том, что фреймворк может использовать неправильный протокол безопасности - и бинго, мои соединения не отклоняются, и я получаю свои данные!
Veverke

7
Важно сказать, что System.Net.ServicePointManager.SecurityProtocol = ...это должно быть выполнено до создания запроса.
Tonatio 02

2
это обновление целевой версии фреймворка до 4.6.1 спасло мне жизнь :-)
Awais

Моя структура установлена ​​на 4.6.2. Возможно, мне придется вместо этого использовать решение TLS
Luminous

Я использую 4.7.2 Framework, также сайт, который я отправляю, использует TLS 1.2, но это похоже на 6 запросов из 10, я получаю эту ошибку. Любые идеи ?
Давид Микучадзе

16

Если вы хотите использовать старую версию .net, создайте свой собственный флаг и примените его.

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }

1
Вам не нужно использовать свой собственный класс, вы можете напрямую ServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
Ян Ф.

13

Добавление приведенного ниже кода помогло мне решить проблему.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

8
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

Это сработало для меня


1
Критическим битом является следующая строка: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; Это замечательный ответ, потому что он показывает, где эта строка должна соответствовать типичному варианту использования.
Ник Пейнтер

5

Я столкнулся с тем же сообщением об ошибке при использовании ChargifyNET.dll для связи с Chargify API. Добавление chargify.ProtocolType = SecurityProtocolType.Tls12;в конфигурацию решило проблему для меня.

Вот полный фрагмент кода:

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}

2

Для VB.NET вы можете разместить следующее перед своим веб-запросом:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

Это решило мою проблему безопасности в .NET 3.5.


0

Это случилось со мной, когда конечная точка веб-запроса была переключена на другой сервер, который принимал только запросы TLS1.2. Пробовал так много попыток, которые в основном можно найти в Stackoverflow, например

  1. Ключи реестра,
  2. Добавлено:
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; в Global.ASX OnStart,
  3. Добавлен в Web.config.
  4. Обновлен .Net framework до 4.7.2. По-прежнему возникает такое же исключение.

Полученное исключение не отражало реальную проблему, с которой я столкнулся, и не нашел помощи со стороны оператора службы.

Чтобы решить эту проблему, мне нужно добавить новый Cipher Suite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384. Я использовал IIS Crypto 2.0 Tool отсюда, как показано ниже.

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.