Is That Possible to Send Httpwebrequest Using Tls1.2 on .Net 4.0 Framework

TLS 1.2 in .NET Framework 4.0

The only way I have found to change this is directly on the code :

at the very beginning of your app you set

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

you should include the system.net class

I did this before calling a web service because we had to block tls1 too.

Issue to use TLS 1.2 in .NET Framework 4.0

According to this post:

.NET 4.0 supports up to TLS 1.0 while .NET 4.5 supports up to TLS 1.2

However, an application targeting .NET 4.0 can still support up to TLS 1.2 if .NET 4.5 is installed in the same environment. .NET 4.5 installs on top of .NET 4.0, replacing System.dll.

So basically you need to upgrade your server to .Net 4.5 to enable TLS 1.2.

Also, you can simplify your code and make it more readable:

using System.Net;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Related MSDN articles:

  • SecurityProtocolType enum for .Net 4.0 (no Tls12 member here)
  • SecurityProtocolType enum for current .Net

Using HttpClient & HttpWebRequest for Https TLS1.2

You need to set the SecurityProtocol property before calling WebRequest.Create method.

Update:

Let me add some details that explain why this should be correct.

Having a look at the source code of WebRequest.Create(string) method from referencesource.microsoft.com.

The return value is:

return Create(new Uri(requestUriString), false);

so now, Let's take a look at Create(Uri, bool) method, it returns some object from WebRequestPrefixElement.Creator.Create(Uri).

Creator is a property inside of WebRequestPrefixElement and it's of type IWebRequestCreate.
In your case, IWebRequestCreate will be an HttpRequestCreator object.

Looking at the code of HttpRequestCreator.Create method:

public WebRequest Create( Uri Uri ) {
//
// Note, DNS permissions check will not happen on WebRequest
//
return new HttpWebRequest(Uri, null);
}

Finally, Let's look at that HttpWebRequest constructor.
You'll see a long code there, but really what is important is this line:

SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;

so the SecurityProtocol value is assigned to a property called SslProtocols.
So, it's obvious now that SecurityProtocol is used and kind of saved to the HttpWebRequest object when you call Create method, so changing SecurityProtocol after calling Create will not change the protocol used by the HttpWebRequest object.

Which versions of SSL/TLS does System.Net.WebRequest support?

When using System.Net.WebRequest your application will negotiate with the server to determine the highest TLS version that both your application and the server support, and use this. You can see more details on how this works here:

http://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake

If the server doesn't support TLS it will fallback to SSL, therefore it could potentially fallback to SSL3. You can see all of the versions that .NET 4.5 supports here:

http://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols(v=vs.110).aspx

In order to prevent your application being vulnerable to POODLE, you can disable SSL3 on the machine that your application is running on by following this explanation:

https://serverfault.com/questions/637207/on-iis-how-do-i-patch-the-ssl-3-0-poodle-vulnerability-cve-2014-3566

Update .NET web service to use TLS 1.2

We actually just upgraded a .NET web service to 4.6 to allow TLS 1.2.

What Artem is saying were the first steps we've done. We recompiled the framework of the web service to 4.6 and we tried change the registry key to enable TLS 1.2, although this didn't work: the connection was still in TLS 1.0. Also, we didn't want to disallow SLL 3.0, TLS 1.0 or TLS 1.1 on the machine: other web services could be using this; we rolled-back our changes on the registry.

We actually changed the Web.Config files to tell IIS: "hey, run me in 4.6 please".

Here's the changes we added in the web.config + recompilation in .NET 4.6:

<system.web>
<compilation targetFramework="4.6"/> <!-- Changed framework 4.0 to 4.6 -->

<!--Added this httpRuntime -->
<httpRuntime targetFramework="4.6" />

<authentication mode="Windows"/>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>

And the connection changed to TLS 1.2, because IIS is now running the web service in 4.6 (told explicitly) and 4.6 is using TLS 1.2 by default.

HttpWebRequest always sending TLS 1.0

I had a similar issue with an Android app I was working on.

It turned out that I had to specifically turn off TLS 1.0, which then allowed newer version of TLS to be tried. I thought it was a stupid problem to have, but what I ended up doing worked, so I wasn't going to complain too hard.

This first article includes a lot of links to pages about auditing your code to see if a method you are using specifically locks you into TLS 1.0, as if you have accidentally hard coded it in.

If you're using a custom binding:
- Configure WCF to allow the OS to choose the best security protocol by
setting SslProtocols to use SslProtocols.None.

- Or configure the protocol used with the configuration path system.serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols.

If you're not using a custom binding and you're setting your WCF binding using configuration, set the protocol used with the configuration path system.serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols.

For .NET Framework 4.6 - 4.6.2 and not WCF
Set the DontEnableSystemDefaultTlsVersions AppContext switch to false. See Configuring security via AppContext switches.

For WCF using .NET Framework 4.6 - 4.6.2 using TCP transport security with Certificate Credentials
You must install the latest OS patches. See Security updates.

The WCF framework automatically chooses the highest protocol available up to TLS 1.2 unless you explicitly configure a protocol version. For more information, see the preceding section For WCF TCP transport using transport security with certificate credentials.

https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls

The above page links to the below link, which is specific to removing TLS 1.0 dependencies from your project in an effort to move to TLS 1.2+.

https://www.microsoft.com/en-us/download/details.aspx?id=55266

  1. Identify all instances of AcquireCredentialsHandle(). This helps reviewers get closer proximity to code blocks where TLS may be hardcoded.
  2. Review any instances of the SecPkgContext_SupportedProtocols and SecPkgContext_ConnectionInfo structures for hardcoded TLS.
  3. In native code, set any non-zero assignments of grbitEnabledProtocols to zero. This allows the operating system to use its default TLS version.
  4. Disable FIPS Mode if it is enabled due to the potential for conflict with settings required for explicitly disabling TLS 1.0/1.1 in this document. See Appendix B for more information.
  5. Update and recompile any applications using WinHTTP hosted on Server 2012 or older.
    a. Applications must add code to support TLS 1.2 via WinHttpSetOption
  6. To cover all the bases, scan source code and online service configuration files for the patterns below corresponding to enumerated type values commonly used in TLS hardcoding:

    a. SecurityProtocolType

    b. SSLv2, SSLv23, SSLv3, TLS1, TLS 10, TLS11

    c. WINHTTP_FLAG_SECURE_PROTOCOL_

    d. SP_PROT_

    e. NSStreamSocketSecurityLevel

    f. PROTOCOL_SSL or PROTOCOL_TLS

That's the meat of the document, but there's more to it than that. I'd suggest checking it out and making sure you aren't accidentally making a mistake or you have legacy code that's preventing you from moving forward. This might be a bit of a rewrite, rather than just a setting, so good luck!

TLS 1.2 not negotiated in .NET 4.7 without explicit ServicePointManager.SecurityProtocol call

I've found one solution. It doesn't answer the question about why TLS 1.2 isn't being used by default on Win10 with .NET 4.7, but it does allow me not to have to set ServicePointManager.SecurityProtocol.

The solution that worked from both my 4.5.2 and 4.7 test apps is to add the following to app.config:

<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>

Here the whole app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
</runtime>
</configuration>


Related Topics



Leave a reply



Submit