Default SecurityProtocol in .NET 4.5

匿名 (未验证) 提交于 2019-12-03 01:29:01

问题:

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

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.0 only support up to TLS 1.0? i.e. I have to upgrade client projects to 4.5 to support TLS 1.2.

My motivation is to remove support for SSLv3 on 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.

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

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

This will make outbound requests to various apis and services to not downgrade to SSLv3 and should select the highest level of 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.0 may be deprecated in the near future by some providers.

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.

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).

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

回答1:

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

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

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

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

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.0 installed, you will get the exception:

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

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

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

  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;

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



回答2:

Some of the those leaving comments have noted that setting System.Net.ServicePointManager.SecurityProtocol to 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.

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

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:

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


回答3:

You can override the default behavior in following registry:

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

For details, please see implementation of ServicePointManager at: http://referencesource.microsoft.com/#System/net/System/Net/ServicePointManager.cs.html%2cbcb6e5c0502bfce6%2creferences



回答4:

Create a text file with a .reg extension and the following contents:

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

Double-click to install...



回答5:

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.

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

The value type needs to be DWORD and value above 0 .Better use 1.



回答6:

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:

  1. Fix the program

Before call HttpWebRequest.GetResponse() add this command:

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

Extensions 2 DLLs by adding 2 new classes: System.Net and 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

Download batch:

  • For windows 2008 R2: windows6.1-kb3154518-x64.msu
  • For 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



回答7:

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;

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



回答8:

For completeness, here is a Powershell script that sets aforementioned registry keys:

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" 


回答9:

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

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

Code

        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. Has no negative impact if SSL3 is already disabled         System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;          Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol); 

Output

48 - SSL3, 192 - TLS1, 768 - TLS1.1, 3072 - TLS1.2

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 


回答10:

An alternative to hard-coding ServicePointManager.SecurityProtocol or the explicit SchUseStrongCrypto key as mentioned above:
You can tell .NET to use the default SCHANNEL settings with the SystemDefaultTlsVersions key,
e.g.:

[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 


回答11:

The BEST solution to this problem appears to be to upgrade to at least .NET 4.6 or later, which will automatically choose strong protocols as well as strong ciphers.

If you can't upgrade to .NET 4.6, the advice of setting

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

And using the registry settings:

Results in using something other than TLS 1.0 and a strong cipher.

In my testing, only the setting in the Wow6432Node made any difference, even though my test application was built for Any CPU.



回答12:

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

You have to set the value to 1.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!