Your .NET Code Could Stop Working in June 2018

TLS changes might leave your .NET 4.5 apps out in the cold

Kyle Gagnet
3 min readMay 11, 2018

Many large companies are still in the process of disabling the outdated SSL 3 and TLS 1.0 security protocols on their servers. Regulations in the Payment Card Industry (PCI) demand that by June 30th 2018 only TLS 1.1 and TLS 1.2 may be enabled. These changes might impact your code even if it is not under the scope of PCI compliance. I’m not going to cover how to enable/disable security protocols on a server. Instead I’m going to present a scenario where client connections (using Microsoft’s .NET Framework) will fail when talking to servers with only TLS 1.1 and/or TLS 1.2 enabled.

What code is impacted?

  • Targets .NET Framework 4.0 or 4.5
  • Uses .NET’s built-in communication framework (HttpClient, HttpWebRequest, etc)
  • Uses default security protocols

When an application targets version 4.0 or 4.5 of the .NET Framework, the default security protocols are SSL 3.0 and TLS 1.0

You might think, “This doesn’t apply to me… my code runs on Windows Server 2016 with .NET 4.7.2 installed”, but you would be wrong.

Don’t believe me? Run the code below (targeting .NET 4.5.2) on a modern, fully-patched operating system:

*DUN DUN DUUUUUN*

What will happen?

If your client code has only SSL 3 and TLS 1.0 enabled when attempting to securely communicate with a server that has only TLS 1.1 and/or TLS 1.2 enabled… it simply won’t work (SocketException). Both server and client must have at least one matching protocol enabled in order to communicate.

What are some options to fix it?

  1. Update your code to explicitly enable the newer protocols.
    This is the option we’re going to explore.
  2. Update your project to target .NET Framework 4.6 or newer.
    This will enable TLS 1.0, TLS 1.1, and TLS 1.2 by default.
  3. Update the registry as described here to enable secure defaults across all .NET applications on the machine.
  4. Rewrite your code to implement a 3rd-party communication framework.

The option you choose depends entirely on your constraints (time, risk, target operating systems, etc). You may not be able to target .NET 4.6 or modify the registry due to a lack of control on your target platform. You might not want to risk rewriting your codebase and retesting.

Thankfully, the code fix is relatively straightforward if you’re targeting .NET 4.5
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

This will ensure that TLS 1.1 and TLS 1.2 are enabled in addition to the system defaults. You can set this once at the beginning of your application to affect all connections in the current AppDomain.

What if I’m targeting .NET 4.0?

Unfortunately, the Tls11 and Tls12values are not defined in .NET 4.0’s version of the SecurityProtocolType enum.

However, if .NET 4.5 or newer is installed on the system, the following code will work at runtime:

Hooray!

Awesome! Is that it? Are all my problems solved?

Not necessarily. The fix above for .NET 4.0 only works if .NET 4.5 is installed on the machine running your code. By default, all versions of Windows starting with Windows 8 ship with .NET 4.5 or newer. So that’s nice.

Unfortunately Windows 7 / Server 2008 only ships with .NET Framework 3.5.1. The solutions for applications targeting .NET 3.5.1 are slightly different than what I’ve covered here. You’ll definitely want to look at Microsoft’s patch for Windows 7 / Server 2008 that enables the new protocols for .NET 3.5.1.

However, there is no patch to enable the protocols for code that targets 4.0. You will have to ensure .NET 4.5 is installed.

--

--

Kyle Gagnet

Lead Software Developer working on enterprise .NET solutions