Default SecurityProtocol in .NET 4.5

前端 未结 17 1385
一生所求
一生所求 2020-11-22 03:24

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

相关标签:
17条回答
  • 2020-11-22 04:09

    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

    0 讨论(0)
  • 2020-11-22 04:11

    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

    Constants:

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

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

    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
    
    0 讨论(0)
  • 2020-11-22 04:13

    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.

    0 讨论(0)
  • 2020-11-22 04:13

    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.Registry settings to get .Net 4.0 app use TLS 1.2 provided .Net 4.5 is installed in the machine.

    0 讨论(0)
  • 2020-11-22 04:14

    There are two possible scenario,

    1. If you application run on .net framework 4.5 or less than that and you can easily deploy new code to the production then you can use of below solution.

      You can add below line of code before making api call,

      ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5

    2. If you cannot deploy new code and you want to resolve with the same code which is present in the production, then you have two options.

    Option 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
    
    
    

    then create a file with extension .reg and install.

    Note : This setting will apply at registry level and is applicable to all application present on that machine and if you want to restrict to only single application then you can use Option 2

    Option 2 : This can be done by changing some configuration setting in config file. You can add either of one in your config file.

    <runtime>
        <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
      </runtime>
    

    or

    <runtime>
      <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"
    </runtime>
    
    0 讨论(0)
  • 2020-11-22 04:17

    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;
    
    0 讨论(0)
提交回复
热议问题