53

My application connects to Experian server and Experian will soon stop supporting TLS 1.0 and TLS 1.1. All connectivity using HTTPS must use TLS Version 1.2.

I want to do some research on that issue and see sending HttpWebRequest using TLS 1.2 on .NET 4.0 framework works

If it does not, I will probably need to create a webservice on .NET 4.5 and call its methods, if it does, I do not have to anything.

Has anyone already faced with that issue?

Liam
  • 22,818
  • 25
  • 93
  • 157
gene
  • 1,762
  • 6
  • 28
  • 74

8 Answers8

103

Yes, it supports it but you must explicitly set the TLS version on the ServicePointManager. Just have this code run anytime (in same app domain) before you make the call to Experian:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12

Update

see @iignatov 's answer for what you must do for framework v4.0. My code works with 4.5+

Liam
  • 22,818
  • 25
  • 93
  • 157
Crowcoder
  • 9,566
  • 3
  • 30
  • 39
  • 1
    I'm trying to implement that change that you suggested and the only `SecurityProtocolType` options I have `Ssl3` and `Tls`. It does not have `Tls12` – gene Jun 16 '16 at 21:05
  • I'm using that myself to call experian so Tim must be right. It is not HttpRequest that is the problem, it is the framework version. – Crowcoder Jun 16 '16 at 21:25
  • As long as you don't have anything at a lower framework level taking a dependency on this code you can just bump up the framework version and add that one line of code. – Crowcoder Jun 16 '16 at 23:00
  • Defining explicitly TLS1.2 breaks compatibility with TLS1.1 or older SSL ? – Agustin Garzon Oct 13 '16 at 12:56
  • 8
    @AgustinGarzon if you want to support other versions you can "or" them together like: `SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls10` – Crowcoder Oct 13 '16 at 13:00
  • This does not work in my 4.0 app, but iignatov's solution does: ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 – jay-danger May 14 '18 at 17:28
  • @jshockwave yes there is no enum value in 4.0 for TLS1.2 so you have to force it. I was not aware of this at the time but my answer continues to get upvoted I think because people are finding this answer even though they are on 4.5. – Crowcoder May 14 '18 at 17:31
  • @Crowcoder please update your answer to indicate this only works for 4.5 and above. Otherwise folks who are looking for a 4.0 solution, which is explicitly what the OP asked for, will be going down the wrong path. – jay-danger May 16 '18 at 16:43
  • If you want to be future proof you shouldn't set it = explicitly, rather add it w/ |= - ie. System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12 – Sean Apr 17 '19 at 13:25
  • @Crowcoder there is no such thing as "SecurityProtocolType.Tls10", there is "SecurityProtocolType.Tls" which actually means Tls 1.0 – Ezh May 29 '19 at 11:38
  • Thanks for this tip. @Crowcoder 's way is true for .Net 4.5 – Sedat Kumcu Mar 24 '21 at 09:13
43

I had to deal with the same problem, while integrating PayPal into a legacy application, and found the following workaround for .NET 4.0 which seems to do the trick:

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
ServicePointManager.DefaultConnectionLimit = 9999;

Basically the workaround is to directly assign the port for TLS 1.2.

All credit goes to the commenter at CodeProject.

iignatov
  • 439
  • 4
  • 2
  • 1
    That magic line did the trick `ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072` Thanks a lot! – Renan Araújo May 16 '17 at 18:55
  • 4
    fyi that hack only works if .net 4.5 is also installed on the server. – CathalMF Jun 20 '18 at 15:42
  • 1
    as @CathalMF mentinoed this works only if .NET 4.5 is installed on the server. Unfortunately 4.5 does not support windows 2003. – Sriwantha Attanayake Mar 12 '20 at 12:02
  • 1
    Is there a reason to explicitly set ServicePointManager.Expect100Continue = true ? How it's related with tls 1.2 support? According to documentation it's anyway true by default.. – leonid p Nov 02 '20 at 09:58
3

The VB.NET Translation of iignatov's answer:

ServicePointManager.Expect100Continue = True
ServicePointManager.SecurityProtocol = CType(3072, SecurityProtocolType)
ServicePointManager.DefaultConnectionLimit = 9999
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
Matt G
  • 41
  • 1
1

You can also use this:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
keremercan
  • 21
  • 4
1

I was solved with this way.

    string url = "https://api.foursquare.com/v2/blablabla...";
    var request = (HttpWebRequest)WebRequest.Create(url);

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
    
    var response = (HttpWebResponse)request.GetResponse();
    var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Sedat Kumcu
  • 1,585
  • 1
  • 12
  • 13
0

FrameWork 4.0 does not support TLS 1.1 or 1.2 But you can fix this problem by downloading Rebex.Http from Nuget manager.

Rebex.Licensing.Key = "..."; //Lisans Number
var creator = new HttpRequestCreator();
creator.Register();

WebRequest request = WebRequest.Create("https://www.test.com");
request.Method = "POST";                
request.Headers.Add("utsToken", txtToken.Text);
request.ContentType = "application/json";
request.Method = "POST";

using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
    string json = "{\"VRG\":\"test\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
    streamWriter.Close();
}

var httpResponse = (WebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    var result = streamReader.ReadToEnd();
    txtSonuc.Text += result;
}
0

I was solved with this way.

string url = "https://api.foursquare.com/v2/blablabla...";
var request = (HttpWebRequest)WebRequest.Create(url);

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Sedat Kumcu
  • 1,585
  • 1
  • 12
  • 13
-1

Unfortunately no, you can't do this. Tls12 was not added until .netfx 4.5 (see the documentation). Note this also requires Windows Server 2008 R2+ or Windows 7+ to run correctly (notice the Applies To section on Introducing TLS).

Tim Copenhaver
  • 3,122
  • 9
  • 18