.net 4.7 не может создать канал SSL, когда сервер отвечает TLS 1.1

Я пытаюсь выполнить HTTPS-запрос GET, используя аутентификацию сертификата клиента, и он не работает с

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

Я пытаюсь выполнить тот же запрос, используя Java, и он отлично работает, я вижу следующее в журналах Java (разделенных только на интересные части):

*** ClientHello, TLSv1.2
main, WRITE: TLSv1.2 Handshake, length = 185

....

*** ServerHello, TLSv1.1
main, READ: TLSv1.1 Handshake, length = 3339

Что, насколько я понимаю, означает, что сервер по какой-то причине не поддерживает TLS 1.2, но клиент принимает это и просто возвращается к TLS 1.1.

Когда я установил

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

.NET тоже работает нормально. Теперь вопрос: почему .NET не возвращается к TLS 1.1, как это сделала Java, могу ли я как-то включить этот откат (без фактической попытки TLS 1.2, поймать исключение и попробовать с TLS 1.1)?


person Giedrius    schedule 18.10.2017    source источник
comment
установите для SecurityProtocol значение SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 ?   -  person Evk    schedule 18.10.2017
comment
Кстати, какая версия Windows установлена ​​на машине, на которой вы запускаете этот код?   -  person Evk    schedule 18.10.2017
comment
Windows 10 15063.608   -  person Giedrius    schedule 18.10.2017
comment
Очень интересно, понятия не имел, что SecurityProtocolType помечен как Flags! И установка значения SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 работает, по умолчанию стоит SSL3 | Тлс. Если бы вы преобразовали комментарий в ответ, я бы отметил его как подтвержденный;)   -  person Giedrius    schedule 18.10.2017
comment
Также, что интересно, проект .net 4.7 и, согласно здесь, он ведет себя как .net 4.5: blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support   -  person Giedrius    schedule 18.10.2017
comment
Мне все еще не очень понятно, почему у вас по умолчанию Ssl3 | Tls. В .NET 4.7 по умолчанию он должен быть SystemDefault. Это полностью чистый проект без каких-либо сопутствующих изменений? Что, если вы просто создадите новый проект и посмотрите, что по умолчанию?   -  person Evk    schedule 18.10.2017
comment
Я попытался создать новое консольное приложение 4.7 .net, и по умолчанию оно все еще было Ssl3 | Tls, когда я добавил ‹AppContextSwitchOverrides value=Switch.System.Net.DontEnableSchUseStrongCrypto=false/›, он изменился на Tls | Тлс11 | Tls12   -  person Giedrius    schedule 18.10.2017


Ответы (1)


В описании ServicePointManager. SecurityProtocol указано

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

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

В то время как в .NET 4.7 значение этого свойства по умолчанию должно быть SystemDefault (источник), а SystemDefault означает запрос ОС о списке протоколов по умолчанию (а в Windows 10 TLS 1.1 и TLS 1.2 enabled) — на это значение по-прежнему могут влиять несколько внешних источников (таких как разделы реестра и см. выше даже по установленному ПО или примененным исправлениям). Как мы выяснили в комментариях, по какой-то причине он у вас по умолчанию Ssl3 | Tls, что плохо, потому что Ssl3 даже не является безопасным и должен быть отключен.

Итак, чтобы решить вашу проблему (и в таких случаях в будущем) - всегда перечисляйте нужные вам протоколы, особенно если вы публикуете свое приложение на нескольких клиентских машинах, потому что настройка по умолчанию ненадежна:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
person Evk    schedule 18.10.2017
comment
Также похоже, что здесь упоминается та же проблема в Windows 10 с .net 4.7: stackoverflow.com/questions/44751179/ - person Giedrius; 18.10.2017
comment
@Гедриус ​​действительно. Но это кажется непоследовательным. Например, у меня такая же версия Windows, как и у вас, но у меня SystemDefault по умолчанию на .NET 4.7. - person Evk; 18.10.2017