Loading [MathJax]/extensions/MathZoom.js

Monday, 17 May 2021

.NET Versions and Transport Layer Security (TLS)

This little blog came about from looking into a strange problem where a query to a rest service was failing with :

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.

System.IO.Exception: Unable to read data from the transport connection: An Existing connection was forcibly closed by the remote host

The cause of this is from an inconsistent security protocol being used by the client and server. In this case the server is using TLSv1.2 and the client SSLv3.

You can get or set the SecurityProtocol in code:

// This needs to be called before the process creates its first connection to the server
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

I'm running this on .NET framework 4.8. So I should be using the SystemDefault protocol for the OS ( Windows 10) which is TLSv1.2. But when I printed out the output from the SecurityProtocol above I got SSLv3 | TLSv1.1 So what's going on?

Supported Runtime

In my app.config file I had the following startup entry:

<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
<supportedRuntime version="v2.0.50727" />
<supportedRuntime version="v4.0" />
</startup>
</configuration>

Documentation here The versions are checked in order with the first one that matches a version installed on your being taken. If that version is present on your computer that will be used.

So with 4.5.2 the default version of SSL3 TLS1 and TLS 1.1 are used. 


There's a few fixes or workarounds for this. First build the code and retarget .NET 4.7.2 or later. Unfortunately this wasn't an option because I didn't own the executable code. This also ruled out explicitly setting the SecurityProtocol in code although this isn't recommended as it makes future changes difficult. You can also edit registry keys (see the link below) to change the default behaviour but I thought this would be too intrusive.

The solution was to add the following to the app.config:

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


For 4.5.2 this also requires the latest patches and registry keys . In an ideal word you would of course update. But software development rarely works in an ideal world.




No comments:

Post a Comment