Протокол безопасности по умолчанию в.NET 4.5
Каков протокол безопасности по умолчанию для связи с серверами, которые поддерживают до 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 (подраздел сервера) и браузерам (подраздел клиента).
Извините, этот пост превратился в несколько вопросов, за которыми последовали ответы "возможно".
14 ответов
По умолчанию 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
это:
- Обновите все приложения до
.NET 4.5
Добавьте следующий код в бустраппинг, чтобы переопределить значение по умолчанию и проверить его на будущее:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
* Кто-то исправит меня, если этот взлом не так, но начальные тесты, я вижу, это работает
Некоторые из тех, кто оставил комментарии, отметили, что 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;
Вы можете переопределить поведение по умолчанию в следующем реестре:
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
,
Создайте текстовый файл с .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
Дважды щелкните, чтобы установить...
Я обнаружил, что когда я указываю только TLS 1.2, он все равно будет переходить к 1.1.System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Я указал это в методе запуска Global.asax для моего веб-приложения.net 4.5.
Следующий код будет:
- протоколы с поддержкой печати
- распечатывать доступные протоколы
- включите 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
Я получил проблему, когда мой клиент обновил TLS с 1.0 до 1.2. Мое приложение использует.net Framework 3.5 и работает на сервере. Итак, я исправил это следующим образом:
- Исправить программу
Перед вызовом 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;
}
}
- Обновление пакета Microsoft
Скачать пакет:
- Для Windows 2008 R2: windows6.1-kb3154518-x64.msu
- Для Windows 2012 R2: windows8.1-kb3154520-x64.msu
Для загрузки пакета и более подробной информации вы можете увидеть здесь:
Механизм изменения реестра работал для меня после борьбы. На самом деле мое приложение работало как 32-битное. Поэтому мне пришлось изменить значение в пути.
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319
Тип значения должен быть DWORD и значение выше 0 . Лучше использовать 1.
Я работаю под.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. неизбежно нарушается, или, скорее всего, вам придется на долгие годы оставлять на сервере существующие незащищенные протоколы, что делает вашу организацию мишенью для атак.
Microsoft недавно опубликовала лучшие практики по этому вопросу. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
Резюме
Цель.Net Framework 4.7, удалить любой код, устанавливающий SecurityProtocol, таким образом, ОС обеспечит вам наиболее безопасное решение.
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.
Для полноты, вот сценарий 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"
Есть два возможных сценария,
Если ваше приложение работает в.NET Framework 4.5 или ниже, и вы можете легко развернуть новый код в производственной среде, вы можете использовать решение ниже.
Вы можете добавить строку кода ниже перед вызовом API,
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5
Если вы не можете развернуть новый код и хотите решить проблему с помощью того же кода, который присутствует в производственной среде, у вас есть два варианта.
Вариант 1:
[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
затем создайте файл с расширением.reg и установите.
Примечание. Этот параметр будет применяться на уровне реестра и применим ко всем приложениям, присутствующим на этом компьютере, и если вы хотите ограничиться только одним приложением, вы можете использовать
Option 2
Вариант 2: это можно сделать, изменив некоторые параметры конфигурации в файле конфигурации. Вы можете добавить любой из них в свой файл конфигурации.
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
</runtime>
или же
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"
</runtime>
Согласно передовым методам безопасности транспортного уровня (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
Лучшее решение этой проблемы, по-видимому, заключается в обновлении до версии.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 имела какое-то значение, хотя мое тестовое приложение было построено для любого процессора.
Альтернатива жесткому кодированию 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
Если вы можете использовать.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.
Для ключа: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319 Значение: SchUseStrongCrypto
Вы должны установить значение 1.