.NET 4.5 中的默认安全协议

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28286086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 09:37:19  来源:igfitidea点击:

Default SecurityProtocol in .NET 4.5

.netsecurityssl

提问by Luke Hutton

What is the default security protocol for communicating with servers that support up to TLS 1.2? Will .NETby default, choose the highest security protocol supported on the server side or do I have to explicitly add this line of code:

与最多支持 的服务器通信的默认安全协议是什么TLS 1.2?将.NET在默认情况下,选择支持在服务器端安全性最高的协议或做我必须明确地添加此行代码:

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

Is there a way to change this default, besides a code change?

除了代码更改之外,有没有办法更改此默认值?

Lastly, does .NET 4.0only support up to TLS 1.0? i.e. I have to upgrade client projects to 4.5 to support TLS 1.2.

最后,是否.NET 4.0只支持最多TLS 1.0?即我必须将客户端项目升级到 4.5 才能支持TLS 1.2.

My motivation is to remove support for SSLv3on the client side even if server supports it (I already have a powershell script to disable this in the machine registry) and to support the highest TLS protocol that the server supports.

我的动机是删除SSLv3对客户端的支持,即使服务器支持它(我已经有一个 powershell 脚本可以在机器注册表中禁用它)并支持服务器支持的最高 TLS 协议。

Update:Looking at the ServicePointManagerclass in .NET 4.0I see no enumerated values for TLS 1.0and 1.1. In both .NET 4.0/4.5, the default is SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Hopefully this default won't break by disabling SSLv3in the registry.

更新:纵观ServicePointManager.NET 4.0我看不出有什么枚举值TLS 1.01.1。在这两种.NET 4.0/4.5情况下,默认值都是SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. 希望此默认设置不会因SSLv3在注册表中禁用而中断。

However, I've decided I have to upgrade all apps to .NET 4.5and to explicitly add SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;anyway to all bootstrapping code of all applications.

但是,我决定我必须将所有应用程序升级到所有应用程序的所有引导代码.NET 4.5并显式添加SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

This will make outbound requests to various apis and services to not downgrade to SSLv3and should select the highest level of TLS.

这将使出站请求各种API和服务,不能降级到SSLv3和应该选择的最高水平TLS

Does this approach sound reasonable or overkill? I have many applications to update, and I want to future proof them since I hear even TLS 1.0may be deprecated in the near future by some providers.

这种方法听起来合理还是矫枉过正?我有很多应用程序需要更新,我想在未来证明它们,因为我听说TLS 1.0某些提供商在不久的将来甚至可能会弃用它们。

As a client making outbound requests to APIs, does disabling SSL3 in the registry even have an effect in the .NET framework? I see by default, TLS 1.1 and 1.2 are not enabled, do we have to enable it via the registry? RE http://support.microsoft.com/kb/245030.

作为向 API 发出出站请求的客户端,在注册表中禁用 SSL3 是否对 .NET 框架也有影响?我看到默认情况下,TLS 1.1 和 1.2 未启用,我们是否必须通过注册表启用它?RE http://support.microsoft.com/kb/245030

After a bit of investigation, I believe the registry settings will have no affect since they apply to IIS (server subkey) and browsers (client subkey).

经过一番调查,我相信注册表设置不会有任何影响,因为它们适用于 IIS(服务器子项)和浏览器(客户端子项)。

Sorry this post turned into multiple questions, followed up with "maybe" answers.

抱歉,这篇文章变成了多个问题,接着是“可能”的答案。

回答by Scott

Some of the those leaving comments have noted that setting System.Net.ServicePointManager.SecurityProtocolto specific values means that your app won't be able to take advantage of future TLS versions that may become the default values in future updates to .NET. Instead of specifying a fixed list of protocols, you can instead turn on or off protocols you know and care about, leaving any others as they are.

一些留下评论的人指出,设置System.Net.ServicePointManager.SecurityProtocol为特定值意味着您的应用程序将无法利用未来的 TLS 版本,这些版本可能成为 .NET 未来更新中的默认值。您可以打开或关闭您知道和关心的协议,而不是指定固定的协议列表,而让其他协议保持原样。

To turn on TLS 1.1 and 1.2 without affecting other protocols:

要在不影响其他协议的情况下打开 TLS 1.1 和 1.2:

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

Notice the use of |=to turn on these flags without turning others off.

请注意使用|=来打开这些标志而不关闭其他标志。

To turn off SSL3 without affecting other protocols:

要在不影响其他协议的情况下关闭 SSL3:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;

回答by Luke Hutton

The default System.Net.ServicePointManager.SecurityProtocolin both .NET 4.0/4.5is SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

System.Net.ServicePointManager.SecurityProtocol.NET 中的默认值4.0/4.5都是SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0supports up to TLS 1.0while .NET 4.5supports up to TLS 1.2

.NET 4.0支持最多TLS 1.0同时.NET 4.5支持最多TLS 1.2

However, an application targeting .NET 4.0can still support up to TLS 1.2if .NET 4.5is installed in the same environment. .NET 4.5installs on top of .NET 4.0, replacing System.dll.

但是,面向应用程序的应用程序.NET 4.0仍然可以支持最多TLS 1.2if.NET 4.5安装在同一环境中。.NET 4.5安装在 之上.NET 4.0,替换System.dll.

I've verified this by observing the correct security protocol set in traffic with fiddler4and by manually setting the enumerated values in a .NET 4.0project:

我已经通过观察流量中设置的正确安全协议fiddler4以及手动设置.NET 4.0项目中的枚举值来验证这一点:

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

Reference:

参考:

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

If you attempt the hack on an environment with ONLY .NET 4.0installed, you will get the exception:

如果您尝试在仅.NET 4.0安装的环境中进行 hack ,您将收到异常:

Unhandled Exception: System.NotSupportedException: The requested security protocol is not supported. at System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType v alue)

未处理的异常:System.NotSupportedException:不支持请求的安全协议。在 System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType 值)

However, I wouldn't recommend this "hack" since a future patch, etc. may break it.*

但是,我不推荐这种“hack”,因为未来的补丁等可能会破坏它。*

Therefore, I've decided the best route to remove support for SSLv3is to:

因此,我决定取消支持的最佳途径SSLv3是:

  1. Upgrade all applications to .NET 4.5
  2. Add the following to boostrapping code to override the default and future proof it:

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

  1. 将所有应用程序升级到 .NET 4.5
  2. 将以下内容添加到 boostrapping 代码以覆盖默认值和未来证明:

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

*Someone correct me if this hack is wrong, but initial tests I see it works

*如果这个 hack 是错误的,有人会纠正我,但初步测试我认为它有效

回答by Jiri Mares

You can override the default behavior in following registry:

您可以覆盖以下注册表中的默认行为:

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

and

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

For details, please see the implementation of ServicePointManager.

有关详细信息,请参阅的实施ServicePointManager

回答by dana

Create a text file with a .regextension and the following contents:

创建一个带有.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

Or download it from the following source:

或从以下来源下载:

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

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

Double-click to install...

双击安装...

回答by Jim

I have found that when I specify only TLS 1.2 that it will still down negotiate to 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

我发现当我只指定 TLS 1.2 时,它仍然会向下协商到 1.1。 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

I have specified this in the Global.asax startup method for my .net 4.5 web app.

我已在 Global.asax 启动方法中为我的 .net 4.5 Web 应用程序指定了这一点。

回答by gerasoras

Following code will:

以下代码将:

  • print enabled protocols
  • print available protocols
  • enable TLS1.2 if platform supports it and if it is not enabled to begin with
  • disable SSL3 if it is enabled
  • print end result
  • 打印启用协议
  • 打印可用的协议
  • 如果平台支持,则启用 TLS1.2,如果开始时未启用
  • 如果启用了 SSL3,则禁用它
  • 打印最终结果

Constants:

常数:

  • 48 is SSL3
  • 192 is TLS1
  • 768 is TLS1.1
  • 3072 is TLS1.2
  • 48 是 SSL3
  • 192是TLS1
  • 768 是 TLS1.1
  • 3072 是 TLS1.2

Other protocols will not be affected. This makes this compatible with future protocols (Tls1.3, etc).

其他协议不会受到影响。这使其与未来的协议(Tls1.3 等)兼容。

Code

代码

// 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);

Output

输出

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

回答by Joy George Kunjikkuru

The registry change mechanism worked for me after a struggle. Actually my application was running as 32bit. So I had to change the value under path.

经过一番挣扎,注册表更改机制对我有用。实际上我的应用程序以 32 位运行。所以我不得不改变路径下的值。

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

The value type needs to be DWORD and value above 0 .Better use 1.Registry settings to get .Net 4.0 app use TLS 1.2 provided .Net 4.5 is installed in the machine.

值类型需要是 DWORD 和大于 0 的值。最好使用 1。获取 .Net 4.0 应用程序的注册表设置使用 TLS 1.2,前提是机器中安装了 .Net 4.5。

回答by Hieu

I got the problem when my customer upgraded TLS from 1.0 to 1.2. My application is using .net framework 3.5 and run on server. So i fixed it by this way:

当我的客户将 TLS 从 1.0 升级到 1.2 时,我遇到了问题。我的应用程序使用 .net framework 3.5 并在服务器上运行。所以我通过这种方式修复了它:

  1. Fix the program
  1. 修复程序

Before call HttpWebRequest.GetResponse() add this command:

在调用 HttpWebRequest.GetResponse() 之前添加以下命令:

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

Extensions 2 DLLs by adding 2 new classes: System.Net and System.Security.Authentication

通过添加 2 个新类扩展 2 个 DLL: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. Update Microsoft batch
  1. 更新微软批次

Download batch:

下载批次:

  • For windows 2008 R2: windows6.1-kb3154518-x64.msu
  • For windows 2012 R2: windows8.1-kb3154520-x64.msu
  • 对于 Windows 2008 R2:windows6.1-kb3154518-x64.msu
  • 对于 Windows 2012 R2:windows8.1-kb3154520-x64.msu

For download batch and more details you can see here:

有关下载批次和更多详细信息,您可以在此处查看:

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-and-server-2008-r2-sp1

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-and-server-2008-r2-sp1

回答by Roger Sanders

I'm running under .NET 4.5.2, and I wasn't happy with any of these answers. As I'm talking to a system which supports TLS 1.2, and seeing as SSL3, TLS 1.0, and TLS 1.1 are all broken and unsafe for use, I don't want to enable these protocols. Under .NET 4.5.2, the SSL3 and TLS 1.0 protocols are both enabled by default, which I can see in code by inspecting ServicePointManager.SecurityProtocol. Under .NET 4.7, there's the new SystemDefaultprotocol mode which explicitly hands over selection of the protocol to the OS, where I believe relying on registry or other system configuration settings would be appropriate. That doesn't seem to be supported under .NET 4.5.2 however. In the interests of writing forwards-compatible code, that will keep making the right decisions even when TLS 1.2 is inevitably broken in the future, or when I upgrade to .NET 4.7+ and hand over more responsibility for selecting an appropriate protocol to the OS, I adopted the following code:

我在 .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;
}

This code will detect when a known insecure protocol is enabled, and in this case, we'll remove these insecure protocols. If no other explicit protocols remain, we'll then force enable TLS 1.2, as the only known secure protocol supported by .NET at this point in time. This code is forwards compatible, as it will take into consideration new protocol types it doesn't know about being added in the future, and it will also play nice with the new SystemDefaultstate in .NET 4.7, meaning I won't have to re-visit this code in the future. I'd strongly recommend adopting an approach like this, rather than hard-coding any particular security protocol states unconditionally, otherwise you'll have to recompile and replace your client with a new version in order to upgrade to a new security protocol when TLS 1.2 is inevitably broken, or more likely you'll have to leave the existing insecure protocols turned on for years on your server, making your organisation a target for attacks.

此代码将检测何时启用了已知的不安全协议,在这种情况下,我们将删除这些不安全协议。如果没有其他显式协议,我们将强制启用 TLS 1.2,这是 .NET 目前唯一支持的已知安全协议。此代码是向前兼容的,因为它将考虑到它不知道将来会添加的新协议类型,并且它也将与新协议兼容SystemDefault.NET 4.7 中的状态,这意味着我将来不必重新访问此代码。我强烈建议采用这样的方法,而不是无条件地硬编码任何特定的安全协议状态,否则您必须重新编译并用新版本替换您的客户端,以便在 TLS 1.2 时升级到新的安全协议不可避免地会被破坏,或者更有可能您必须在服务器上启用现有的不安全协议多年,从而使您的组织成为攻击目标。

回答by JohnLBevan

Microsoft recently published best practices around this. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Microsoft 最近发布了有关此的最佳实践。 https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Summary

概括

Target .Net Framework 4.7, remove any code setting the SecurityProtocol, thus the OS will ensure you use the most secure solution.

针对 .Net Framework 4.7,删除任何设置 SecurityProtocol 的代码,因此操作系统将确保您使用最安全的解决方案。

NB: You will also need to ensure that the latest version of TLS is supported & enabled on your OS.

注意:您还需要确保您的操作系统支持和启用最新版本的 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

For more information and older frameworks, please refer to the MS link.

有关更多信息和旧框架,请参阅 MS 链接。