96

I am developing a TCP client to connect OpenSSL server with the certificate authentication. I have using .crt and .key files shared by server team. These certificates are generated by OpenSSL commands.

I am using SslStream object to authenticate the Tcp client by calling SslStream.AuthenticateAsClient method by passing server IP, SslProtocols.Ssl3 and X509CertificateCollection.

I am getting the following error:

Authentication failed because the remote party has closed the transport stream

halfer
  • 19,824
  • 17
  • 99
  • 186
Odelu
  • 969
  • 1
  • 7
  • 7
  • 2
    This looks like a problem in the post-POODLE days: `SslProtocols.Ssl3`. Maybe you should try `SslProtocols.Tls`. In .Net 4.5 and above, you can also use `Tls11` or `Tls12`. See [SslProtocols Enumeration](https://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols%28v=vs.85%29.aspx). You may have other problems. – jww Jun 05 '15 at 10:57
  • Also see [Socket and Authentication failed because the remote party has closed the transport stream exception in WPF](http://stackoverflow.com/q/27840644). – jww Jun 05 '15 at 11:04
  • Thanks. My problem is solved by attaching the certificate from the physical path of certificate and password instead of searching certificate subject name from windows certificate store. – Odelu Jun 08 '15 at 07:13
  • Now i am able to get the result from all the SslProtocols(SSL3,Tls1 and Tls2).Thanks for reply – Odelu Jun 08 '15 at 07:14
  • @Odelu, how did you fixed the problem? On client side or server side? –  Aug 31 '15 at 17:46

10 Answers10

179

I would advise against restricting the SecurityProtocol to TLS 1.1.

The recommended solution is to use

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

Another option is add the following Registry key:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

It is worth noting that .NET 4.6 will use the correct protocol by default and does not require either solution.

Diogo Cid
  • 3,764
  • 1
  • 20
  • 25
GuiSim
  • 7,361
  • 6
  • 40
  • 50
  • 8
    wow, you just sorted out my problem - I was trying all sort of things - and then ended up here seeing the note on the framework. Just switched it to 4.6.1 (was using 4.5), hoping the problem would be the framework might be using the wrong security protocol - and bingo, my connections are not being refused, and I am getting my data! – Veverke Jun 16 '16 at 15:31
  • 8
    It is important to say that `System.Net.ServicePointManager.SecurityProtocol = ...` has to be executed before creating the request. – Tonatio Oct 02 '18 at 19:35
  • 3
    that target framework version update to 4.6.1 saved my life :-) – Awais Dec 24 '18 at 04:38
  • My framework is set at 4.6.2. Maybe I'll have to use the TLS solution instead – Luminous Mar 19 '19 at 16:09
  • i'm using 4.7.2 Framework also the site which i'm sending request is using TLS 1.2 but its like at 6 requests from 10 i get this error. any ideas ? – Davit Mikuchadze Jan 03 '20 at 14:43
  • I am on 4.6.1 and the recommend solution fixed it right before my api call. Not sure what changed on my email service provider server? – tvb108108 Jan 25 '20 at 00:55
  • This line worked for me: `[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072` – Justin Russell Aug 31 '23 at 15:25
19

If you want to use an older version of .net, create your own flag and cast it.

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }
Iguanaware
  • 376
  • 2
  • 6
  • 4
    You don't have to use your own class, you can directly cast integers to SecurityProtocolType `ServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;` – Yan F. Oct 09 '17 at 02:56
  • @YanF. Author mentioned `If you use older .Net version...`, so there it helps. Like .Net 4.0 – Gray Programmerz Mar 31 '23 at 14:18
12

Adding the below code helped me overcome the issue.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
muruge
  • 4,083
  • 3
  • 38
  • 45
11
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

This worked for me

Sanket Sonavane
  • 391
  • 2
  • 10
  • 1
    The critical bit is the following line: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; This answer is great though because it shows where that line should fit within the typical use case. – Nick Painter May 16 '19 at 19:12
  • If it's outside those brackets does not it work as intended? – pete Apr 27 '23 at 05:17
5

I ran into the same error message while using the ChargifyNET.dll to communicate with the Chargify API. Adding chargify.ProtocolType = SecurityProtocolType.Tls12; to the configuration solved the problem for me.

Here is the complete code snippet:

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}
Tod Birdsall
  • 17,877
  • 4
  • 38
  • 40
3

For VB.NET, you can place the following before your web request:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

This solved my security issue on .NET 3.5.

user1477388
  • 20,790
  • 32
  • 144
  • 264
1

This happened to me when an web request endpoint was switched to another server that accepted TLS1.2 requests only. Tried so many attempts mostly found on Stackoverflow like

  1. Registry Keys ,
  2. Added :
    System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12; to Global.ASX OnStart,
  3. Added in Web.config.
  4. Updated .Net framework to 4.7.2 Still getting same Exception.

The exception received did no make justice to the actual problem I was facing and found no help from the service operator.

To solve this I have to add a new Cipher Suite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 I have used IIS Crypto 2.0 Tool from here as shown below.

enter image description here

FunMatters
  • 593
  • 1
  • 10
  • 26
0

I faced the following issues in VS 2019:

  • Sing in isn't working
  • Extensions -> Manage Extensions -> extension information couldn't be retrieved.

I've added a new Cipher Suite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 as FunMatters explain. This resolved my issues as well.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 01 '22 at 12:03
0

At .NET framework 4.8 I added following code before sending request.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ysk silver
  • 160
  • 10
0

I had this problem and fixed it but none of the solutions found here at the time of this post (ie, TSL solutions) worked for me, tried them every which way. I spent several hours trying, searching, trying, everything seemed to focus on TSL problems, none of these solved the problem for me.

What I had to do was use Visual Studio Installer and do a repair to my VS installation. After that, it was fixed right away.

Cobysan
  • 99
  • 6
  • The problem could be your way of focusing in article or solutions, just like TSL :) – Shan May 05 '23 at 07:23