C# – SoapHttpClientProtocol and TLS 1.2 – The client and server cannot communicate, because they do not possess a common algorithm

csslwsdl

There are numerous posts on SO about this and I have scoured them, but still don't have a solution. I am hoping that someone can point me in the right direction.

We have a requirement now to use TLS 1.2 to connect to a remote provider. So I have installed Windows Server 2016 and configured it as needed:

enter image description here
enter image description here

I know the remote server is running TLS 1.2 and that it supports the highlighted cipher.

We connect to the remote end point using C# proxy class generated by the WSDL provided by the provider – before they converted their end to TLS (System.Web.Services.Protocols.SoapHttpClientProtocol).

When I connect using the proxy I get an exception with the inner exception being "The client and server cannot communicate, because they do not possess a common algorithm".

I cannot see anywhere that ServicePointManager.SecurityProtocol so I am assuming .NET is picking up TLS 1.2 as it is the only enabled protocol? No idea how it is doing the cipher.

Can someone tell me how I go about attempting to fix this? If possible I don't want to regenerate the WSDL proxy class.

Best Answer

If your client application was compiled against .NET Framework 4.5.2 or lower, then by default ServicePointManager.SecurityProtocol is initialized to SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls (SSL 3.0 and TLS 1.0 only), so it won't be able to connect to a remote server that requires TLS 1.2.

There are several ways to allow your client application to use TLS 1.2:

  • Recompile your client application against .NET Framework 4.6 or later. (In Visual Studio, open your project's property pages, go to the Application tab, and change the Target Framework.)
  • On the client machine, run RegEdit.exe, go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ .NETFramework\v4.0.30319, add a DWORD (32-bit) value named SchUseStrongCrypto, and set it to 1. (This flag causes ServicePointManager.SecurityProtocol to be initialized to Tls | Tls11 | Tls12.)
  • When your client application starts up, turn on TLS 1.2: ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

There's no need to regenerate your proxy class because it's not responsible for negotiating the TLS protocol or cipher.