3
votes

I have a .NET 4.8 application which is a small Excel Add-in (thus running in Office/Excel) which performs HTTP (REST) requests and shows the data in Excel.

On the webserver we reconfigured to only allow TLS 1.2 and suddenly the HTTP Requests do not work anymore with this WebException: The underlying connection was closed: An unexpected error occurred on a send.

Test-client OSes are Windows 10 and 8 (fully patched). Thus supporting TLS 1.2 according to https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls : "Supported, and enabled by default."

Executing the following in PowerShell gives:

[Net.ServicePointManager]::SecurityProtocol
SystemDefault

The following registry keys - which are often mentioned in documentation and blogs - are NOT set (they do not exist - also not the WOW6432Node variants):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SystemDefaultTlsVersions
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp\DefaultSecureProtocols

Setting HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto=1 "fixes" the problem.

I can also manually enable TLS 1.2 and the problem goes away, but that removes control from the OS back to the application, which does not seem to be the underlying idea of .NET 4.8: ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

My questions:

  • How can I find out what SystemDefault evaluates to in .NET. How can I find this?
  • Why does TLS 1.2 not seem to enabled without setting registry keys?
  • My assumption is that TLS 1.2 should be supported with .NET 4.8 without any system modifications (like registry keys) and without any code changes. Is this assumption wrong?

Addition I found these Github .net issues which seem to describe what I experience:

GitHub: Not getting default values on .NET 4.7.2 on Windows 10 (1709)

GitHub: The Windows 10 .Net 4.8 Oct update removes TLS 1.1, 1.2. 1.3 from default security protocols from .Net apps forcing traffic to use SSL3 and TLS 1.0.

Unfortunately I have no machines old enough to not have the KB update yet. I may not be asking at the right place here, but is it possible that .NET 4.8 requires registry keys to get proper TLS 1.2 working?

2
Are you sure the error isn't due to incomplete TLS1.3 support??Panagiotis Kanavos
Yes I am sure. We only enabled TLS 1.2 serverside.Bossk
UPDATE: I still don't have a solution and am really stumped why TLS 1.2 is not enabled. I checked multiple Windows 10 machine, none have the SchUseStrongCrypto key. Any ideas?Bossk
Just throwing this out there. I have battled with this myself and just add in the TLS 1.2 value. Once the value is in place, it takes affect immediately. Take a look at this: pastebin.com/0v5quVJL It only affects the current user, not the entire machine.Andy
Note that in that code, all Protocols are enabled for testing, you should enable only what you want to support. You can also add the option, for the Users, to enable other protocols, if needed. -- Anyway, read my first comment: if you could make it work setting SchUseStrongCrypto = 1 in the Registry, then you're not using .Net 4.8: that .Net version has automatic opt-in for this (the Registry key is useless). You can only opt-out. Check your build and the dependencies / libraries / whatever that query HTTPS resources.Jimi

2 Answers

1
votes

The default setting in .NET versions is related to the operating systems it can run on. Several older versions of Windows do not support TLS 1.2 So the default for .NET is use what ever setting the Operating System is using. While both Windows 10 and 8 support TLS 1.2 it is not enabled by default.

The link below is Microsoft's documentation on how to enable TLS 1.2 on most versions of Windows. It specifically mentions setting the following two registry settings:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp\
      DefaultSecureProtocols = (DWORD): 0xAA0
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp\
      DefaultSecureProtocols = (DWORD): 0xAA0

https://docs.microsoft.com/en-us/mem/configmgr/core/plan-design/security/enable-tls-1-2-client

Update

A couple of other areas that could cause this problem:

  1. Just because you are compiling against .NET 4.8 doesn't mean your app is configured to run on 4.8. It will default to what ever version of .NET it was originally compiled to run on. So if it was version 4.6 or older that may be the issue.

  2. Older versions of Office will only work against certain versions of .NET https://docs.microsoft.com/en-us/visualstudio/vsto/running-solutions-in-different-versions-of-microsoft-office?view=vs-2019

In the following document on TLS best practices it states

Do not specify the TLS version. Configure your code to let the OS decide on the TLS version.

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

-1
votes

I have recently been through the same painful process of getting TLS 1.2 to work. In general there are three thing to look out for.

  • You should let .NET use the system default and not try to override it in code like setting ServicePointManager.SecurityProtocol.
  • Second thing to watch out for is that both the .net version and the OS must support TLS 1.2
  • Lastly the cipher suite used to secure the TLS 1.2 tunnel must be supported by both sides.

What helped me a lot was this overview and guidelines from MS TLS best practices

So to answer your questions:

  1. It depends on the OS, use the link to find out the specifics
  2. Again it depends on the .net version and the os
  3. And again it depends on the os