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
For Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319 Value: SchUseStrongCrypto
You have to set the value to 1.
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
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:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319 – SchUseStrongCrypto = DWORD of 1 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319 – SchUseStrongCrypto = DWORD of 1
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.
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.
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 SystemDefault
protocol 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:
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 SystemDefault
state 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.
If you can use .NET 4.7.1 or newer, it will use TLS 1.2 as the minimum protocol based on the operating system capabilities. Per Microsoft recommendation :
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.