December 5, 2017
Is It Time to Update that ASP.NET Web Forms Project?
Recently, a legacy ASP.NET Web API application that we support started logging an exception and also giving back a HTTP 500 response on some of its API endpoints. The exception, or at least an inner exception within it, was:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel
With SSL3 and TLS1.0 being deprecated, I figured this had to do with a version mismatch between the browser and the server. In fact, that was true. The reason why the security protocol didn’t default to TLS 1.2 in my application is because it was running on .NET 4.6.2, and in .NET 4.6x there is no default set for the security protocol. Also, it was running on a version of Windows (2012 R2) that didn’t have newer versions of TLS enabled by default.
One solution to this is to recompile your website either specifying a default or targeting .NET 4.7, which does have a default value of SecurityProtocolType.SystemDefault. According to the Microsoft .NET documentation, this setting “allows .NET Framework networking APIs based on SslStream (such as FTP, HTTP, and SMTP) to inherit the default security protocols from the operating system or from any custom configurations performed by a system administrator”. In my case, that may not have helped since the OS didn’t have TLS1.2 enabled.
I wasn’t able to recompile the application at the time, anyway, and so needed to find another way to fix the issue by reconfiguring the OS. In the end, I was able to fix the issue by enabling something called “strong cryptography mode” in Windows on the web server, which you can read more background about here.
To make the change, I simply had to run the two commands below in an elevated PowerShell prompt on the server. The first command is for x64 .NET and the second for x86 .NET.
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
After those commands are run, you can run the following command to verify the setup:
This will list the enabled SSL/TLS protocols, which in my case now includes TLS12 (that is, TLS 1.2).
Finally, I simply reset IIS to restart my application, and I now no longer get the “Could not create SSL/TLS secure channel” exception and the API longer returns HTTP 500 responses!