Протокол безопасности по умолчанию в .NET 4.5

254

Каков протокол безопасности по умолчанию для связи с серверами, которые поддерживают до TLS 1.2? Будет ли .NETпо умолчанию, выберите самый высокий протокол безопасности , поддерживаемый на стороне сервера или у меня явно добавить эту строку кода:

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

Есть ли способ изменить это значение по умолчанию, кроме изменения кода?

Наконец, поддерживает .NET 4.0только до TLS 1.0? т.е. я должен обновить клиентские проекты до 4.5 для поддержки TLS 1.2.

Моя мотивация состоит в том, чтобы удалить поддержку SSLv3на стороне клиента, даже если сервер поддерживает ее (у меня уже есть сценарий powershell, чтобы отключить это в реестре компьютера), и поддерживать самый высокий протокол TLS, который поддерживает сервер.

Обновление: глядя на ServicePointManagerкласс, .NET 4.0я не вижу перечислимых значений для TLS 1.0и 1.1. В обоих случаях .NET 4.0/4.5по умолчанию SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Надеюсь, это значение по умолчанию не будет нарушено при отключении SSLv3в реестре.

Тем не менее, я решил, что мне нужно обновить все приложения .NET 4.5и явно SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;все равно добавить их во весь загрузочный код всех приложений.

Это будет делать исходящие запросы к различным API и службам, чтобы не понизить до SSLv3и должен выбрать самый высокий уровень TLS.

Этот подход звучит разумно или излишне? У меня есть много приложений, которые нужно обновить, и я хочу проверить их в будущем, поскольку, как я слышал TLS 1.0, некоторые провайдеры могут даже отказаться от них в ближайшем будущем.

Является ли клиент, отправляющий исходящие запросы к API, влияет ли отключение SSL3 в реестре на платформу .NET? Я вижу, по умолчанию TLS 1.1 и 1.2 не включены, мы должны включить его через реестр? RE http://support.microsoft.com/kb/245030 .

После небольшого исследования я считаю, что настройки реестра не окажут никакого влияния, поскольку они применяются к IIS (подраздел сервера) и браузерам (подраздел клиента).

Извините, этот пост превратился в несколько вопросов, за которыми последовали ответы «возможно».

Люк Хаттон
источник
К вашему сведению: последние передовые практики в отношении TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/…
JohnLBevan
Для тех, кто хочет увидеть лучший ответ, сортируйте по голосам!
Навуле
1
Связанные SO Q & A: stackoverflow.com/questions/41618766/... Следует обратить внимание читателей на этот вопрос не стареет , и новые рекомендации на месте , как в 2020 году
Нет возвратов не возвращал

Ответы:

281

Некоторые из тех, кто оставил комментарии, отметили, что установка System.Net.ServicePointManager.SecurityProtocolопределенных значений означает, что ваше приложение не сможет использовать преимущества будущих версий TLS, которые могут стать значениями по умолчанию в будущих обновлениях .NET. Вместо того, чтобы указывать фиксированный список протоколов, вы можете вместо этого включать или выключать известные вам протоколы и заботиться о них, оставляя все остальные как есть.

Чтобы включить TLS 1.1 и 1.2 без влияния на другие протоколы:

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

Обратите внимание на использование |=этих флагов без выключения других.

Чтобы отключить SSL3 без влияния на другие протоколы:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
Скотт
источник
6
Это действительно правильный ответ. Принятый ответ гарантирует, что ваше приложение всегда будет отключать новые версии TLS, если вы не вернетесь и не обновите свой код.
Коннор
5
@Gertsen Нет, это побитовый или, так что он просто включает соответствующие биты, если они выключены. Если эти биты уже включены, никаких изменений не происходит.
Скотт
3
И эквивалентом PowerShell является [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod, основанный на тех же базовых библиотеках .NET Framework.
Мартин Холлингсворт
15
Поскольку никто не говорит о том, где разместить этот код, я успешно поместил его в Application_Start файла Global.asax.cs для моего приложения ASP.NET MVC. Я искал, как получить мои SMTP-запросы для отправки через TLS1.2, а не через TLS1.0. Я также добавил & = ~ SecurityProtocolType.Tls, чтобы отключить TLS 1.0
Грег Верес
2
В VB эквивалентNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codespaced
188

По умолчанию System.Net.ServicePointManager.SecurityProtocolв обоих .NET 4.0/4.5есть SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0поддерживает до, TLS 1.0пока .NET 4.5поддерживает доTLS 1.2

Однако, нацеливание приложение .NET 4.0все еще может поддерживать до , TLS 1.2если .NET 4.5установлен в той же среде. .NET 4.5устанавливается поверх .NET 4.0, заменяя System.dll.

Я проверил это, соблюдая правильный протокол безопасности, установленный в трафике, fiddler4и вручную задавая перечисляемые значения в .NET 4.0проекте:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 |
(SecurityProtocolType)768 | (SecurityProtocolType)3072;

Ссылка:

namespace System.Net
{
    [System.Flags]
    public enum SecurityProtocolType
    {
       Ssl3 = 48,
       Tls = 192,
       Tls11 = 768,
       Tls12 = 3072,
    }
}

Если вы попытаетесь взломать среду, в которой .NET 4.0установлено ТОЛЬКО , вы получите исключение:

Необработанное исключение: System.NotSupportedException: запрошенный протокол безопасности не поддерживается. в System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

Тем не менее, я бы не рекомендовал этот «взлом», поскольку будущий патч и т. Д. Может его сломать. *

Поэтому я решил, что лучший способ удалить поддержку SSLv3- это:

  1. Обновите все приложения до .NET 4.5
  2. Добавьте следующее в код бустрапинга, чтобы переопределить значение по умолчанию и проверить его на будущее:

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

* Кто-то исправит меня, если этот взлом не так, но начальные тесты, я вижу, это работает

Люк Хаттон
источник
6
См. Imperialviolet.org/2014/12/08/poodleagain.html «Это хороший момент для того, чтобы повторить, что все, кроме TLS 1.2 с набором шифров AEAD, криптографически повреждено».
Нил
3
@Mathew, просмотрев исходный код ServicePointManager.csсм referencesource.microsoft.com/#System/net/System/Net/...
Luke Hutton
12
Я продолжаю видеть, как люди утверждают, что по .NET 4.5умолчанию Tls12 - но, как вы указали здесь, это не так. Это дает вам возможность использовать его дляSecurityProtocol
Дон Чидл
17
Я не буду опровергать этот ответ, так как он предоставляет много полезной информации, но реализация версии протокола с жесткой кодировкой не является хорошей идеей, поскольку она ограничит использование приложением наилучшего доступного шифрования и может привести к проблемам с безопасностью в будущем. Изменения в реестре для изменения поведения .Net по умолчанию для поддержки современных протоколов очень предпочтительны. (Однако стоит отметить, что изменение реестра также отключает SSL v3.)
AJ Henderson
6
На FW 4.6 и 4.7 значение по умолчанию теперь SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12соответствует support.microsoft.com/en-us/help/3069494/…
Ian Kemp
68

Вы можете переопределить поведение по умолчанию в следующем реестре:

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

и

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

Для получения подробной информации, пожалуйста, смотрите реализациюServicePointManager .

Иржи Марес
источник
Спасибо, я не знал об этом. Я проверю это. Я создал сценарий powershel для его установки: gist.github.com/lukehutton/ab80d207172a923401b1
Люк Хаттон,
6
Изменение реестра не выглядит хорошим решением. Если приложение хочет поддерживать TLS1, приложение должно позаботиться об этом. Не бегущая среда. В противном случае это может нанести вред другим приложениям или стать адом для развертывания и обновления вашего приложения.
Михаил Г
13
@MikhailG совсем наоборот. Изменение реестра является предпочтительным методом. SChannel предоставляет абстракцию базового согласования, и вы хотите, чтобы ваше приложение использовало любой поддерживаемый уровень безопасности. Искусственное ограничение его в программном обеспечении может привести к проблемам в будущем, когда будут выпущены новые протоколы, и ваше программное обеспечение не сможет их использовать. Было бы неплохо, если бы была возможность сказать, что в программном обеспечении используется только лучше, чем данный протокол, но для этого не существует возможности, не препятствующей работе будущих версий. Это отключило SSL v3 с этим изменением ..
AJ Henderson
13
Командная строка: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(и / или /reg:32)
Кевин Смит
7
@MikhailG: Настройка реестра не мешает приложениям поддерживать старые протоколы. Это только изменяет значения по умолчанию (которые включают tls 1.0 на данный момент). Кроме того, по умолчанию в .Net 4.6+ используется сильная криптография; в этом случае эта запись реестра будет полезна только в качестве средства отключения сильной криптографии.
Брайан
51

Создайте текстовый файл с .regрасширением и следующим содержимым:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

Или загрузите его из следующего источника:

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg

Дважды щелкните, чтобы установить ...

Dana
источник
3
Похоже, что указанная вами ссылка имеет проблемы с сертификатом SSL.
NathanAldenSr
Даже когда я добавляю эти ключи реестра, у меня все еще есть эта проблема. Любая идея ?
Самиджо
@Samidjo - Какую версию .NET вы используете? Ответ Люка более детален, чем мой, но похоже, что вам нужно, по крайней мере, установить .NET 4.5. Кроме того, если вы только что внесли изменения, вам, возможно, придется перезапустить пул приложений. Это своего рода догадки, так что без более подробной информации я мог бы помочь гораздо дальше :)
Дана
2
Недавно примененный патч support.microsoft.com/en-us/help/4019114/… к серверу вызвал сбой нашего приложения .net 4.5.2 при запросах https REST. Эти ключи решили нашу проблему.
Kleinux
21

Я обнаружил, что когда я указываю только TLS 1.2, он все равно будет переходить к 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Я указал это в методе запуска Global.asax для моего веб-приложения .net 4.5.

Джим
источник
2
Какой протокол безопасности поддерживается на сервере? Я считаю, что это фактор здесь и может быть 1.1 является последним на сервере. www.passionatecoder.ca
Ehsan
14
Проголосовал, потому что это единственный ответ, в котором говорится, ГДЕ поставить строку кода, которая является решением.
Jgerman
1
Клиент (например, ваш C # WebClient) и Сервер (сервер API, к которому вы обращаетесь) будут согласовывать использование самого высокого протокола, который оба поддерживают. Так что, если ваш клиент поддерживает TLS 1.2, но сервер только TLS 1.1 - Клиент будет использовать TLS 1.1 (если вы не УДАЛИТЕ TLS 1.1 со своего клиента - в этом случае они могут не найти взаимно поддерживаемый протокол, и Клиент выдаст ошибку)
Дон Чедл
Пришлось добавить использование System.Net в global.asax.cs
Патрик,
16

Следующий код будет:

  • протоколы с поддержкой печати
  • распечатывать доступные протоколы
  • включите TLS1.2, если платформа поддерживает его, и если он не включен для начала
  • отключить SSL3, если он включен
  • конечный результат печати

Константы:

  • 48 - это SSL3
  • 192 - это TLS1
  • 768 - это TLS1.1
  • 3072 - это TLS1.2

Другие протоколы не будут затронуты. Это делает это совместимым с будущими протоколами (Tls1.3 и т. Д.).

Код

// print initial status
    Console.WriteLine("Runtime: " + System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion);
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);
    Console.WriteLine("Available protocols: ");
    Boolean platformSupportsTls12 = false;
    foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) {                
        Console.WriteLine(protocol.GetHashCode());
        if (protocol.GetHashCode() == 3072){
            platformSupportsTls12 = true;
        }
    }
    Console.WriteLine("Is Tls12 enabled: " + ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072));    


// enable Tls12, if possible
    if (!ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072)){
        if (platformSupportsTls12){
            Console.WriteLine("Platform supports Tls12, but it is not enabled. Enabling it now.");
            ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072;
        } else {
            Console.WriteLine("Platform does not supports Tls12.");
        }
    }

// disable ssl3
   if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Ssl3)) { 
      Console.WriteLine("Ssl3SSL3 is enabled. Disabling it now.");
      // disable SSL3. Has no negative impact if SSL3 is already disabled. The enclosing "if" if just for illustration.
      System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;                      
   }
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);

Вывод

Runtime: 4.7.2114.0
Enabled protocols:   Ssl3, Tls
Available protocols: 
0
48
192
768
3072
Is Tls12 enabled: False
Platform supports Tls12, but it is not enabled. Enabling it now.
Ssl3 is enabled. Disabling it now.
Enabled protocols:   Tls, Tls12
gerasoras
источник
14

Я получил проблему, когда мой клиент обновил TLS с 1.0 до 1.2. Мое приложение использует .net Framework 3.5 и работает на сервере. Итак, я исправил это следующим образом:

  1. Исправить программу

Перед вызовом HttpWebRequest.GetResponse () добавьте эту команду:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

Расширения 2 DLL путем добавления 2 новых классов: System.Net и System.Security.Authentication

    namespace System.Net
    {
        using System.Security.Authentication;
        public static class SecurityProtocolTypeExtensions
        {
            public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
            public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11;
            public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0;
        }
    } 

    namespace System.Security.Authentication
    {
        public static class SslProtocolsExtensions
        {
            public const SslProtocols Tls12 = (SslProtocols)0x00000C00;
            public const SslProtocols Tls11 = (SslProtocols)0x00000300;
        }
    } 
  1. Обновление пакета Microsoft

Скачать пакет:

  • Для Windows 2008 R2: windows6.1-kb3154518-x64.msu
  • Для Windows 2012 R2: windows8.1-kb3154520-x64.msu

Для загрузки пакета и более подробной информации вы можете увидеть здесь:

https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-.net-framework-3.5.1-on-windows-7 -sp1-и-сервер-2008-r2-sp1

Хьеу
источник
1
Возможно ли изменить SecurityProtocol без изменения исходного кода? как machine.config или app.config.
аханкенди
1
Вот это да. Это награда вуду года .. материал ... прямо там. Вы качаете пригород!
granadaCoder
14

Механизм изменения реестра работал для меня после борьбы. На самом деле мое приложение работало как 32-битное. Поэтому мне пришлось изменить значение в пути.

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319

Тип значения должен быть DWORD и значение выше 0. Лучше использовать 1.Настройки реестра для получения приложения .Net 4.0 используют TLS 1.2 при условии, что на машине установлен .Net 4.5.

Джой Джордж Кунджиккуру
источник
Это не точно. Для .NET 4.5.2 это должно быть установлено в 1 (или выше); но для .NET 4.6 достаточно не быть установленным в 0 (то есть он может быть не установлен).
Йирка Ханика
О, я не тестировал в .Net 4.6. Мои выводы есть в блоге joymonscode.blogspot.com/2015/08/…
Джой Джордж Кунджиккуру
Раздел реестра, который вы упоминаете, должен прочитать «Wow6432Node». Вы по какой-то причине пропустили часть «Узел». Я пытался отредактировать ваш ответ, но мое изменение было всего 4 письма, поэтому он не позволил мне. : \
Джеффри Лекурс
Я должен был отскочить IIS, чтобы этот параметр сам по умолчанию был активным.
Джефф Митчелл
10

Я работаю под .NET 4.5.2, и я не был доволен ни одним из этих ответов. Поскольку я говорю о системе, которая поддерживает TLS 1.2 и видит, что SSL3, TLS 1.0 и TLS 1.1 все сломаны и небезопасны для использования, я не хочу включать эти протоколы. В .NET 4.5.2 протоколы SSL3 и TLS 1.0 включены по умолчанию, что можно увидеть в коде по проверке ServicePointManager.SecurityProtocol. В .NET 4.7 есть новыйSystemDefaultРежим протокола, который явно передает выбор протокола в ОС, где я полагаю, что использование реестра или других параметров конфигурации системы будет уместным. Похоже, что это не поддерживается в .NET 4.5.2. В интересах написания форвард-совместимого кода, он будет продолжать принимать правильные решения, даже когда TLS 1.2 неизбежно сломается в будущем или когда я обновлю до .NET 4.7+ и передам больше ответственности за выбор подходящего протокола для ОС. Я принял следующий код:

SecurityProtocolType securityProtocols = ServicePointManager.SecurityProtocol;
if (securityProtocols.HasFlag(SecurityProtocolType.Ssl3) || securityProtocols.HasFlag(SecurityProtocolType.Tls) || securityProtocols.HasFlag(SecurityProtocolType.Tls11))
{
    securityProtocols &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11);
    if (securityProtocols == 0)
    {
        securityProtocols |= SecurityProtocolType.Tls12;
    }
    ServicePointManager.SecurityProtocol = securityProtocols;
}

Этот код будет определять, когда включен известный небезопасный протокол, и в этом случае мы удалим эти небезопасные протоколы. Если не останется никаких других явных протоколов, мы принудительно включим TLS 1.2, как единственный известный безопасный протокол, поддерживаемый .NET на данный момент. Этот код совместим с предыдущими версиями, так как он будет учитывать новые типы протоколов, которые он не знает о добавлении в будущем, и он также будет хорошо работать с новымSystemDefaultукажите в .NET 4.7, что означает, что мне не придется повторно посещать этот код в будущем. Я бы настоятельно рекомендовал принять такой подход, а не жестко кодировать какие-либо конкретные состояния протокола безопасности безоговорочно, в противном случае вам придется перекомпилировать и заменить свой клиент новой версией, чтобы перейти на новый протокол безопасности при TLS 1.2. неизбежно нарушается, или, скорее всего, вам придется на долгие годы оставлять незащищенные протоколы включенными на вашем сервере, что делает вашу организацию мишенью для атак.

Роджер Сандерс
источник
1
Этот ответ кажется наиболее продуманным, однако, если я что-то упустил, я не уверен, что он будет совместим с прямой пересылкой всякий раз, когда TLS 1.2 неизбежно ломается. Из того, что я вижу в моем приложении .NET 4.7.2, этот SecurityProtocolType.SystemDefaultфлаг оценивается как 0, поэтому проверка if (securityProtocols == 0)с помощью побитового включения или флага для TLS 1.2 всегда будет включать в себя TLS 1.2, даже после того, как он "сломается", верно? Не резкая стрельба здесь. Я искренне пытаюсь найти лучший путь вперед.
Griswald_911
Я изменил свой код , чтобы включить это и он , как представляется , работать и быть совместимыми: if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911
@ Griswald_911, у меня есть подобный код в моем консольном приложении 4.7.2, и я обнаружил, что эта строка securityProtocols |= SecurityProtocolType.Tls12;(без блока if) не поддерживает SystemDefault, а у securityProtocols только TLS2. Итак, вы имеете в виду, когда значение равно SystemDefault, никакое значение не должно обновляться? Что касается прямой совместимости, вы предполагаете, что ОС позаботится о включении более нового протокола, такого как TLS 1.3?
Ян
@ Ян - Верно. У строки securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum есть [Flags]атрибут, а значение перечисления 0SystemDefault равно значению SystemDefault, которое будет удалено, даже если оно было установлено ранее. Конечным результатом является то, что вы можете установить SevicePointManager.SecurityProtocol значение 0 или любую комбинацию других значений перечисления. Если вы установите его в SystemDefault, вы в основном отказываетесь от указания протокола самостоятельно и позволяете операционной системе решать.
Griswald_911
1
@Yang - Дело в том, что после установки значения SystemDefault ваше приложение должно использовать все, что указывает ОС - это TLS 1.2 в последних версиях Windows 10. Идея заключается в том, что в будущем, когда TLS 1.3 станет стандарт, вам не нужно изменять свое приложение для наследования этой функциональности. Смотрите документацию здесь , где SystemDefault «позволяет операционной системе выбирать лучший протокол для использования и блокировать незащищенные протоколы».
Griswald_911
6

Microsoft недавно опубликовала лучшие практики по этому вопросу. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Резюме

Задайте .Net Framework 4.7, удалите любой код, устанавливающий протокол безопасности, поэтому ОС обеспечит вам наиболее безопасное решение.

NB. Вам также необходимо убедиться, что последняя версия TLS поддерживается и включена в вашей ОС.

OS                          TLS 1.2 support

Windows 10                  \_ Supported, and enabled by default.
Windows Server 2016         /   
Windows 8.1                 \_ Supported, and enabled by default.
Windows Server 2012 R2      /
Windows 8.0                 \_ Supported, and enabled by default.
Windows Server 2012         /
Windows 7 SP1               \_ Supported, but not enabled by default*.
Windows Server 2008 R2 SP1  /
Windows Server 2008         -  Support for TLS 1.2 and TLS 1.1 requires an update. See Update to add support for TLS 1.1 and TLS 1.2 in Windows Server 2008 SP2.
Windows Vista               -  Not supported.

* To enable TLS1.2 via the registry see https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

Для получения дополнительной информации и более старых платформ, пожалуйста, обратитесь к ссылке MS.

JohnLBevan
источник
3
Проблема в том, что tls 1.1 и tls 1.2 не будут работать в Windows 7 и Server 2008, если вы будете следовать рекомендациям (сохраняя SecurityProtocolType.SystemDefault), потому что они не «включены» (что бы это ни значило) в этих ОС без изменения реестра. Это делает SystemDefault на практике нарушенным по замыслу. Microsoft действительно испортила это.
osexpert
Хороший, спасибо @osexpert, хороший улов. Я изменил ответ, включив информацию о поддерживаемых ОС, поэтому для людей, работающих под управлением старых ОС, нет сюрпризов, для которых недостаточно только ориентации на 4.7.
JohnLBevan
1
NB. Существует также КБ для включения новых протоколов в некоторых операционных системах: support.microsoft.com/en-my/help/3140245/…
JohnLBevan
1
Если параметры реестра не подходят, я думаю, что это лучшее решение для .NET 4.7+: if (System.Environment.OSVersion.Version < new Version(6, 2) /* Windows 8 */) ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; else ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
osexpert
5

Для полноты вот сценарий Powershell, который устанавливает вышеупомянутые ключи реестра:

new-itemproperty -path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord";
new-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord"
Qbik
источник
2

Альтернатива жесткому кодированию ServicePointManager.SecurityProtocolили явный ключ SchUseStrongCrypto, как упомянуто выше:
.NET может использовать стандартные настройки SCHANNEL с ключом SystemDefaultTlsVersions,
например:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
Альфред
источник
2

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

Если вы не можете перейти на .NET 4.6, совет по настройке

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

И используя настройки реестра:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD из 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = 1

В результате получается что-то отличное от TLS 1.0 и надежный шифр.

В моем тестировании только настройка в Wow6432Node имела какое-то значение, хотя мое тестовое приложение было построено для любого процессора.

GWC
источник
Пояснение: вам нужно только установить SevicePointManager.SecurityProtocol ИЛИ установить параметры реестра. Там нет необходимости делать оба. Для моего приложения я решил установить ServicePointManager.SecurityProtocol. Я рассуждаю так: настройка реестра влияет на всю машину, и я не хотел, чтобы чьи-то приложения ломались, потому что это зависело от TLS 1.0.
GWC
1

Согласно рекомендациям Transport Layer Security (TLS) с .NET Framework : Для обеспечения безопасности приложений .NET Framework версия TLS не должна быть жестко закодирована. Вместо этого установите ключи реестра: SystemDefaultTlsVersions и SchUseStrongCrypto :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
Бенджамин Фрейтаг
источник
0

Если вы можете использовать .NET 4.7.1 или новее, он будет использовать TLS 1.2 в качестве минимального протокола, основанного на возможностях операционной системы. По рекомендации Microsoft:

To ensure .NET Framework applications remain secure, the TLS version should not be hardcoded. .NET Framework applications should use the TLS version the operating system (OS) supports.
yanivhs
источник
-2

Для ключа: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Значение: SchUseStrongCrypto

Вы должны установить значение 1.

KGW
источник
5
Я думаю, что вы получаете отрицательный голос, потому что это тот же ответ, который предложил @Jira Mares, но с меньшим количеством деталей
Стюарт Зиглер