4

I'm connecting to a 3rd party API using HttpWebRequest and getting failures ("Underlying Connection closed") that the API doesn't support the version of TLS that's used for the request. I inspect the request in Fiddler and see that my request is sending TLS 1.0.

I've tried setting the newer TLS / SSL version on the global ServicePointManager as recommended in many, many answers here on SO (and tried many different flavors of setting setting that), but even after setting that before the request is made, I still get the same error and I inspect in Fiddler and see that the request is still using TLS 1.0!. It's like my attempt at using ServicePointManager is not having any effect at all.

My DLL making the request is on .NET 4.6.1, and consuming DLL also on .NET 4.6.1, so I don't think framework version is the culprit.

Any ideas or guidance is greatly appreciated!!!

unnknown
  • 1,715
  • 2
  • 19
  • 37

3 Answers3

3

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!

computercarguy
  • 2,173
  • 1
  • 13
  • 27
  • "Set the DontEnableSystemDefaultTlsVersions AppContext switch to false. See Configuring security via AppContext switches" ... this is what worked for me. No WCF used in my request, just am using the HttpWebRequest object to manually submit http request. Since I had windows 7 I also had to turn on tls 1.1 and 1.2 in my registry settings... had done that previously, but this app.config setting appears to have been what I was missing – unnknown Aug 12 '19 at 03:23
1

The framework is the culprit. The problem is that .NET Framework starting from version 4.6 is not allowing SSL as it is considered vulnerable.

Workaround

To work around this issue, update the server to Tls 1.0, Tls 1.1, or Tls 1.2 because SSL 3.0 has been shown to be unsecure and vulnerable to attacks such as POODLE.

Note If you cannot update the server, use AppContext class to opt out of this feature.

To do this, use one of the following methods:

Programmatically: Must be the very first thing the application does because ServicePointManager will initialize only once. Use the following code example in your application:

private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching";
        private const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto";
        AppContext.SetSwitch(DisableCachingName, true);
        AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, true);

By using the AppConfig file for your application: Add the following line to the Appconfig file:

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

More info on link below.

Cannot connect to a server by using the ServicePointManager or SslStream APIs after upgrade to the .NET Framework 4.6

dropoutcoder
  • 2,627
  • 2
  • 14
  • 32
  • 1
    I think in my case it was the publisher of the API no longer allowing SSL and instead only allowing TLS 1.1 or TLS 1.2, rather than my framework upgrade causing an issue with old (insecure) SSL. But good to know... – unnknown Aug 12 '19 at 03:26
-1

I think there is a registry setting you might need to change Please follow the following reference links

From StackOverflow

another source

Microsoft

shobhonk
  • 621
  • 5
  • 15