39

Our .net WCF Client, the WebRequest call, compiled to a windows EXE, running on Win2012-R2, refuses to connect to a web server that surfaces ONLY TLS 1.2

We know that Win2012 and .NET 4.5x support TLS 1.2

We have no problems when the server surfaces TLS 1.0 and up. The problem is only seen when the server we connect to has DISABLED TLS 1.0, 1.1 and SSL2 and SSL3. The Server ONLY surfaces TLS 1.2. Chrome and firefox (on Win 7 and higher) connect fine to the server (no warnings or SSL issues of any kind).

The server certificate is %100 OK.

The problem is that WebRequest fails to connect in this situation.

What do we need to set in code so that our use of WebRequest will connect to systems that may run TLS 1.2, 1.1, 1.0, and/or SSL v3?

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Jonesome Reinstate Monica
  • 6,618
  • 11
  • 65
  • 112
  • More than likely, this is the ciphers enabled on the OS. What OS are you using? Have you applied all patches and service packs? Did you try updating to .NET 4.5.2? – Erik Funkenbusch Apr 16 '15 at 02:01
  • @ErikFunkenbusch No, sorry, you are not correct. This is not an issue of cipher enablement (On Win2012-R2, all the ciphers are present and all are enabled.) Nor is it a limitation of .NET 4.51, TLS 1.2 support is present in .NET 4.x. The question is how to enable it, as .NET itself is not enabled for 1.2 by default. – Jonesome Reinstate Monica Apr 16 '15 at 04:17
  • Are you saying it won't connect to any secure connection for any site? – Erik Funkenbusch Apr 16 '15 at 06:33
  • @ErikFunkenbusch Please refer to the OP. The issue is that WebRequest, when used directly, on Win2012-R2 under .NET 4.51 fails to connect to a server if the server surfaces ONLY TLS 1.2 – Jonesome Reinstate Monica Apr 16 '15 at 14:50
  • I did refer to the post, and your post suggests that it doesn't connect to "TLS 1.2, 1.1, 1.0, and/or SSL v3" which to me suggests it won't connect to any secure connection. So, i'm asking... does it connect successfully to any of those other services? Further, you didn't include any code demonstrating what you're doing, so it's a little hard to know what you may be doing wrong. – Erik Funkenbusch Apr 16 '15 at 14:52
  • 1
    Also, are you certain the servers certificate is valid? Have you tried bypassing certificate validation to verify if that's the issue? Have you also set `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12`? – Erik Funkenbusch Apr 16 '15 at 14:57
  • @ErikFunkenbusch Apologies. The OP must have been misleading. I just did a big expansion to the OP. – Jonesome Reinstate Monica Apr 16 '15 at 15:07
  • Some code would be useful to diagnose the issue. Can you also provide the full error message? – Patrick Hofman Apr 16 '15 at 15:09
  • It appears this thread has the answer: http://stackoverflow.com/q/26389899/147637 – Jonesome Reinstate Monica Apr 16 '15 at 15:45
  • That just says what I asked you above... sheesh. – Erik Funkenbusch Apr 16 '15 at 16:03

3 Answers3

41

You should work with .NET 4.5 or above version and add this line in your code:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Hand-E-Food
  • 12,368
  • 8
  • 45
  • 80
Yujie
  • 442
  • 5
  • 2
  • 4
    You don't have to touch code: https://learn.microsoft.com/en-us/officeonlineserver/enable-tls-1-1-and-tls-1-2-support-in-office-online-server – Sean Anderson Jan 25 '18 at 17:49
  • 5
    your code is wiping out whatever value *was* in SecurityProtocol and leaving *only* TLS1.2. Some webservices may still be on TLS1.1. To add TLS1.2 as a possible option, along with others, use `|=` more detail https://www.ryadel.com/en/asp-net-client-server-cannot-comunicate-because-they-possess-common-algorithm-how-to-fix-c-sharp/ – Don Cheadle Nov 05 '18 at 01:10
38

While not easy to figure out, the needed property is:

System.Net.ServicePointManager.SecurityProtocol

This can be used to disable and enable TLS levels in the WCF environment.

Further, you can see what WCF is currently set to using:

Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol.ToString());

With thanks to: How do I disable SSL fallback and use only TLS for outbound connections in .NET? (Poodle mitigation)

Community
  • 1
  • 1
Jonesome Reinstate Monica
  • 6,618
  • 11
  • 65
  • 112
  • 1
    Is the Windows server version relevant to the fix, or does it work regardless of your Windows version as long as you set `System.Net.ServicePointManager.SecurityProtocol` appropriately? – Don Cheadle Mar 09 '16 at 19:35
  • 3
    @mmcrae The windows version is relevant to the degree that if the OS itself does not support TLS 1.2 (via schannel dll), then asking for it in .NET is not going to give it to you... See https://blogs.msdn.microsoft.com/kaushal/2011/10/02/support-for-ssltls-protocols-on-windows/ – Jonesome Reinstate Monica Mar 10 '16 at 04:54
  • While this answer is correct, it sets a program wide setting. What if I want to use different protocol for different service calls in the same program? – Esko May 20 '16 at 09:01
  • 1
    @Esko You can't, that's the only possible setting, a clear design flaw of .NET Framework. [This thread](http://stackoverflow.com/q/3791629/2557263) shows the problem and proposes solutions. Microsoft, of course, [has carefully ignored the problem](https://connect.microsoft.com/VisualStudio/feedback/details/605185/cant-set-the-security-protocol-per-servicepoint). – Alejandro Oct 18 '16 at 12:43
0

What is important, you should start with .Net Framework v4.5 at least. Older versions do not support TSL 1.2. Later on, while authenticating to the server explicitly use this protocol:

    sslStream.AuthenticateAsClient(this._configuration.Host, null, SslProtocols.Tls12, true);
J.Wincewicz
  • 849
  • 12
  • 19