TLS 1.2 support in .NET framework
With new .NET (Core) versions being released every year, we might quickly forget that there are still many old .NET framework applications in use without being regularly updated. Recently I helped to fix one such application as it suddenly stopped working because of a failing SSL/TLS connection:
The underlying connection was closed: An unexpected error occurred on a send.
Depending on the API used to establish the connection, it could also be:
The request was aborted: Could not create SSL/TLS secure channel.
A common reason for these kinds of errors is a failed TLS handshake because there is no TLS version that is supported both by the client and the server. For .NET framework 4.5 applications, this could be because the server only supports TLS 1.2+, and the .NET framework client only supports TLS 1.0 and 1.1. TLS 1.2 wasn't supported until .NET framework 4.6.
To see which TLS versions a server supports, you can run an SSL server test. The results will clearly show which protocol versions are supported and which aren't:
To check and change the Target framework for a .NET framework project, open the Application tab in the project properties window in Visual Studio. To support TLS 1.2, you should change it at least to .NET framework 4.6, but unless you have a good reason not to, you should just pick the latest available version (.NET framework 4.8.1 at the time of writing).
For ASP.NET applications, you will also have to make a manual change in the Web.config
file. The change in the project properties should have already changed the targetFramework
value in the compilation
element:
<system.web>
<compilation debug="true" targetFramework="4.6.2"/>
</system.web>
And it should have also added a comment suggesting another change:
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.6.2" />
</system.Web>
-->
To make TLS 1.2 work in your application, you need to follow this suggestion and also change the targetFramework
value in the httpRuntime
element:
<system.web>
<httpRuntime targetFramework="4.6.2"/>
</system.web>
Once you recompile and redeploy your application with these changes, the TLS handshake problem should be gone.
You can find a sample application with this issue in my GitHub repository. In the last commit, the issue is already fixed with a target framework change. In the previous commit, the application home page will fail to load because of missing TLS 1.2 support.
Many servers have been removing support for TLS 1.0 and TLS 1.1 which can break old .NET framework applications because there was no support for TLS 1.2 before .NET framework 4.6. If your application suddenly stops working, this could be the reason. You can check if that's the case with an SSL server test and after confirming it, change the target framework to fix the issue.