Simon Dugré
Simon Dugré

Reputation: 18946

The request was aborted: Could not create SSL/TLS secure channel

We are unable to connect to an HTTPS server using WebRequest because of this error message:

The request was aborted: Could not create SSL/TLS secure channel.

We know that the server doesn't have a valid HTTPS certificate with the path used, but to bypass this issue, we use the following code that we've taken from another StackOverflow post:

private void Somewhere() {
    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AlwaysGoodCertificate);
}

private static bool AlwaysGoodCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) {
   return true;
}

The problem is that server never validates the certificate and fails with the above error. Does anyone have any idea of what I should do?

Upvotes: 739

Views: 1652794

Answers (30)

APW
APW

Reputation: 354

The top-voted answer will probably be enough for most people. However, in some circumstances, you could continue getting a "Could not create SSL/TLS secure channel" error even after forcing TLS 1.2. If so, you may want to consult this helpful article for additional troubleshooting steps. To summarize: independent of the TLS/SSL version issue, the client and server must agree on a "cipher suite." During the "handshake" phase of the SSL connection, the client will list its supported cipher-suites for the server to check against its own list. But on some Windows machines, certain common cipher-suites may have been disabled (seemingly due to well-intentioned attempts to limit attack surface), decreasing the possibility of the client & server agreeing on a cipher suite. If they cannot agree, then you may see "fatal alert code 40" in the event viewer and "Could not create SSL/TLS secure channel" in your .NET program.

The aforementioned article explains how to list all of a machine's potentially-supported cipher suites and enable additional cipher suites through the Windows Registry. To help check which cipher suites are enabled on the client, try visiting this diagnostic page in Internet Explorer. (Using System.Net tracing may give more definitive results.) To check which cipher suites are supported by the server, try this online tool (assuming that the server is Internet-accessible). It should go without saying that Registry edits must be done with caution, especially where networking is involved. (Is your machine a remote-hosted VM? If you were to break networking, would the VM be accessible at all?)

In my company's case, we enabled several additional "ECDHE_ECDSA" suites via Registry edit, to fix an immediate problem and guard against future problems. But if you cannot (or will not) edit the Registry, then numerous workarounds (not necessarily pretty) come to mind. For example: your .NET program could delegate its SSL traffic to a separate Python program (which may itself work, for the same reason that Chrome requests may succeed where Internet Explorer requests fail on an affected machine).

Upvotes: 16

Jon Schneider
Jon Schneider

Reputation: 26983

Another possible cause of this error is a mismatch between your client PC's configured cipher_suites values, and the values that the server is configured as being willing and able to accept. In this case, when your client sends the list of cipher_suites values that it is able to accept in its initial SSL handshaking/negotiation "Client Hello" message, the server sees that none of the provided values are acceptable, and may return an "Alert" response instead of proceeding to the "Server Hello" step of the SSL handshake.

To investigate this possibility, you can download Microsoft Message Analyzer, and use it to run a trace on the SSL negotiation that occurs when you try and fail to establish an HTTPS connection to the server (in your C# app).

If you are able to make a successful HTTPS connection from another environment (e.g. the Windows XP machine that you mentioned -- or possibly by hitting the HTTPS URL in a non-Microsoft browser that doesn't use the OS's cipher suite settings, such as Chrome or Firefox), run another Message Analyzer trace in that environment to capture what happens when the SSL negotiation succeeds.

Hopefully, you'll see some difference between the two Client Hello messages that will allow you to pinpoint exactly what about the failing SSL negotiation is causing it to fail. Then you should be able to make configuration changes to Windows that will allow it to succeed. IISCrypto is a great tool to use for this (even for client PCs, despite the "IIS" name).

The following two Windows registry keys govern the cipher_suites values that your PC will use:

  • HKLM\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002
  • HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002

Here's a full writeup of how I investigated and solved an instance of this variety of the problem: http://blog.jonschneider.com/2016/08/fix-ssl-handshaking-error-in-windows.html

Upvotes: 25

Simon Dugré
Simon Dugré

Reputation: 18946

In newer environments that support or enforce newer versions of SSL (TLS), you must add this before the code that makes an HTTP request:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons

Upvotes: 910

Andrej Z
Andrej Z

Reputation: 2781

The solution to this, in .NET 4.5+ is

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

If you don’t have .NET 4.5 then use

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

Upvotes: 278

saqibhaneef
saqibhaneef

Reputation: 81

I was getting this issue in the vb.net windows form.

Tried adding multiple security protocols as mentioned in the above answers.

ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | 
SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | 
SecurityProtocolType.Ssl3;

Nothing was working.

But this is how I resolve

Turn off the Windows Defender firewall as shown in the image below enter image description here and change the system to the domain network (you can ask your network department to change the system to the domain). After that I used SecurityProtocolType.Tls12 and it works.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Upvotes: 2

Shirish Patel
Shirish Patel

Reputation: 63

If you mention an incorrect Host then also you will get this same error "The request was aborted: Could not create SSL/TLS secure channel."

To solve this I had to give the correct Host. Most of the times the Host is the domain of the URL you are trying to GET. e.g.

URL : The request was aborted: Could not create SSL/TLS secure channel

Host : https://stackoverflow.com

client.Headers.Add(HttpRequestHeader.Host, Host.ToString());

Upvotes: 1

In my case I had this problem when a Windows service tried to connected to a web service. Looking in Windows events finally I found a error code.

Event ID 36888 (Schannel) is raised:

The following fatal alert was generated: 40. The internal error state is 808.

Finally it was related with a Windows Hotfix. In my case: KB3172605 and KB3177186

The proposed solution in vmware forum was add a registry entry in windows. After adding the following registry all works fine.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman]

"ClientMinKeyBitLength"=dword:00000200

Apparently it's related with a missing value in the HTTPS handshake in the client side.

List your Windows HotFix:

wmic qfe list

Solution Thread:

https://communities.vmware.com/message/2604912#2604912

Upvotes: 2

joeydood
joeydood

Reputation: 51

I was having this same issue and found this answer worked properly for me. The key is 3072. This link provides the details on the '3072' fix.

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

XmlReader r = XmlReader.Create(url);
SyndicationFeed albums = SyndicationFeed.Load(r);

Upvotes: 5

SpoiledTechie.com
SpoiledTechie.com

Reputation: 10725

Something the original answer didn't have. I added some more code to make it bullet proof.

ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

Upvotes: 20

Priyank Sharma
Priyank Sharma

Reputation: 181

Try adding the below line before calling an HTTPS URL (for .NET Framework 4.5):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Upvotes: 17

Muhammad Amin
Muhammad Amin

Reputation: 1203

These steps worked for me,for Windows Server 2012 R2.

  1. First install any pending Windows Updates and Restart Server.
  2. Go to SSLLabs https://www.ssllabs.com/ssltest/analyze.html
  3. Enter the url of the site/api you are having problem to connect, wait a while until the test is completed
  4. Go to 'Cipher Suites' section and read very carefully TLS 1.3 / TLS 1.2. There you will find the Cipher Suites accepted by the server.
  5. Download IISCrypto GUI tool from https://www.nartac.com/Products/IISCrypto/Download
  6. Enable TLS 1.2, if it is disabled. (using IISCrypto GUI Tool)
  7. Enable additional/missing cipher suites you found in point No. 5 (using IISCrypto GUI Tool).
  8. Restart Server.

Upvotes: 0

ekalchev
ekalchev

Reputation: 972

In case you already have this

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

in your code and you or your clients still get this error here what I found that works for my company:

We are seeing more and more error coming from newer versions of Windows OS and I believe the reason for that is that Microsoft is starting to decommission older TLS version in latest windows updates and they are not supported by the Windows OS anymore. It seems this enum above is used during socket handshake where security protocol is negotiated. By having enum set like this you are falsely advertising support of security protocol that is not supported by the OS. When the secure channel is opened and one of non supported protocols were negotiated, between client and server, you end up with the above error. Starting with .net framework 4.7 you should not explicitly set Security protocol and leave with its default value which is actually a set of protocols that are supported by the OS. This way you won't negotiate not supported protocol and won't get the error we are talking about.

Upvotes: 2

pompiamp
pompiamp

Reputation: 71

We had the same problem in a client Windows Server 2012R2. The error 40 means that the client and the server does not agree with the cipher suite to use. In most cases, the server requires a cipher suite that the client does not recognize.

If you cannot modify server settings, the solution is to add those "missing" cipher suites to the client this way:

  1. First, go to SSLLabs SSL Labs
  2. Enter the url of the site/api you are having problem to connect
  3. Wait a few minutes until the test is completed
  4. Go to 'Cipher Suites' section and read very carefully TLS 1.3 / TLS 1.2
  5. There you will find the Cipher Suites accepted by the server
  6. Now in your windows server, go to Regedit
  7. Open the Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL
  8. There you will find 2 folders: 00010002 -->TLS 1.2 and 00010003 --> TLS 1.3
  9. Now, edit the Functions key, and add the suites required by the server
  10. In our case, we needed to Add TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 to 00010002 folder

Upvotes: 6

OfirD
OfirD

Reputation: 10490

Another possibility is that the code being executed doesn't have the required permissions.

In my case, I got this error when using Visual Studio debugger to test a call to a web service. Visual Studio wasn't running as Administrator, which caused this exception.

Upvotes: 6

MYriad
MYriad

Reputation: 118

Most answers above mention session algorithms or key exchange algorithms.

In my case both were OK and the problem was in server's certificate hash algorithm, that was not enabled on client's PC.

I figured it out adding a section to my application's config.

<system.diagnostics>
    <trace autoflush="true" />
    <sources>
        <source name="System.Net">
            <listeners>
                <add name="System.Net" />
            </listeners>
        </source>
        <source name="System.Net.Sockets">
            <listeners>
                <add name="System.Net" />
            </listeners>
        </source>
        <source name="System.Net.Cache">
            <listeners>
                <add name="System.Net" />
            </listeners>
        </source>
    </sources>
    <sharedListeners>
        <add
            name="System.Net"
            type="System.Diagnostics.TextWriterTraceListener"
            initializeData="System.Net.trace.log"
        />
    </sharedListeners>
    <switches>
        <add name="System.Net" value="Verbose" />
        <add name="System.Net.Sockets" value="Verbose" />
        <add name="System.Net.Cache" value="Verbose" />
    </switches>
</system.diagnostics>

And then error in log led me to this solution

Upvotes: 4

user19916900
user19916900

Reputation:

After days of pulling what hair I have left out, we solved the problem. I tried everything suggested on this post and nothing worked for me. For us, we had a basic .Net Framework 4.8 console app running on a customers Windows VM. The on-premise server we were communicating with required that SSL Certificate Validation was turned off. One of our guys discovered that the server required we were using TLS 1.0 and on the registry settings of the VM, TLS 1.0 was disabled. Once we enabled that, it worked. I also needed to added the following two lines as mentioned many times above:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Upvotes: 1

Michael Silver
Michael Silver

Reputation: 473

This question can have many answers since it's about a generic error message. We ran into this issue on some of our servers, but not our development machines. After pulling out most of our hair, we found it was a Microsoft bug.

https://support.microsoft.com/en-us/help/4458166/applications-that-rely-on-tls-1-2-strong-encryption-experience-connect

Essentially, MS assumes you want weaker encryption, but the OS is patched to only allow TLS 1.2, so you receive the dreaded "The request was aborted: Could not create SSL/TLS secure channel."

There are three fixes.

  1. Patch the OS with the proper update: http://www.catalog.update.microsoft.com/Search.aspx?q=kb4458166

  2. Add a setting to your app.config/web.config file (as mentioned in the above link):

    <runtime>
       <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
    </runtime>
  1. Add a registry setting that was already mentioned in another answer.

All of these are mentioned in the knowledge base article I posted.

Upvotes: 3

Dinesh Rajan
Dinesh Rajan

Reputation: 2584

In my case, the service account running the application did not have permission to access the private key. Once I gave this permission, the error went away

  1. mmc
  2. certificates
  3. Expand to personal
  4. select cert
  5. right click
  6. All tasks
  7. Manage private keys
  8. Add the service account user

Upvotes: 13

JayTee
JayTee

Reputation: 486

In my case, I was running under Visual Studio 2022. Time and time again I was getting this error. Going through the code I saw that it retrieved the certificate just fine. Security was set to TLS1.2, both answers above. For whatever reason, running Visual Studio as Administrator made it work! Maybe someone can explain to me how the code retrieved the certificate from the store just fine. I could see it and all the properties. Why in the name of this world would it not process the request unless I run VS in admin mode???

Upvotes: 3

Amer Jamaeen
Amer Jamaeen

Reputation: 776

I know it's late answer but I faced the same issue when I try to call API (hosted on win server 2016) from win server 2012 R2 (client)

After a lot of investigation the issue was related to handshake issue on operating system level specifically the list of ciphers from client is not supported by the host server.

I got to know the issue when I used Wireshark to trace the connection and I found out that the sent cipher is not supported.

Window server 2012 R2 has limited support to new ciphers which might cause TLS/SSL handshake.

the starting point was when I saw this error "A fatal alert was received from the remote endpoint. The TLS protocol defined fatal alert code is 40" in event viewer (Event Viewer >> Custom Views >> Administrative Events))

Upvotes: 4

JLRishe
JLRishe

Reputation: 101748

Note: Several of the highest voted answers here advise setting ServicePointManager.SecurityProtocol, but Microsoft explicitly advises against doing that. Below, I go into the typical cause of this issue and the best practices for resolving it.

One of the biggest causes of this issue is the active .NET Framework version. The .NET framework runtime version affects which security protocols are enabled by default.

  • In ASP.NET sites, the framework runtime version is often specified in web.config. (see below)
  • In other apps, the runtime version is usually the version for which the project was built, regardless of whether it is running on a machine with a newer .NET version.

There doesn't seem to be any authoritative documentation on how it specifically works in different versions, but it seems the defaults are determined more or less as follows:

Framework Version Default Protocols
4.5 and earlier SSL 3.0, TLS 1.0
4.6.x TLS 1.0, 1.1, 1.2, 1.3
4.7+ System (OS) Defaults

For the older versions, your mileage may vary somewhat based on which .NET runtimes are installed on the system. For example, there could be a situation where you are using a very old framework and TLS 1.0 is not supported, or using 4.6.x and TLS 1.3 is not supported.

Microsoft's documentation strongly advises using 4.7+ and the system defaults:

We recommend that you:

  • Target .NET Framework 4.7 or later versions on your apps. Target .NET Framework 4.7.1 or later versions on your WCF apps.
  • Do not specify the TLS version. Configure your code to let the OS decide on the TLS version.
  • Perform a thorough code audit to verify you're not specifying a TLS or SSL version.

For ASP.NET sites: check the targetFramework version in your <httpRuntime> element, as this (when present) determines which runtime is actually used by your site:

<httpRuntime targetFramework="4.5" />

Better:

<httpRuntime targetFramework="4.7" />

Upvotes: 84

Taylor G
Taylor G

Reputation: 898

For SOAP/WCF users, this error can also occur when the server rejects your WS-Security configuration. The error information the client receives is very vague, but the server administrator will likely be able to determine the reason.

Once example of this is under the UsernameToken Profile, where the message is considered expired by the <wsu:Created> time is not a valid ISO 8601 datetime, either due to bad formatting, not being UTC, or having mismatched server times.

<wsse:UsernameToken wsu:Id="Example-1">
   <wsse:Username> ... </wsse:Username>
   <wsse:Password Type="..."> ... </wsse:Password>
   <wsse:Nonce EncodingType="..."> ... </wsse:Nonce>
   <wsu:Created>2021-01-31T19:00:00.0000000Z</wsu:Created>
</wsse:UsernameToken>

Upvotes: 1

Zireael
Zireael

Reputation: 1035

Delete this option from registry helped me in Windows Server 2012 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangAlgorithms

enter image description here

Upvotes: -1

Merlyn007
Merlyn007

Reputation: 465

Doing this helped me:

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

Upvotes: 14

Jon Schneider
Jon Schneider

Reputation: 26983

"The request was aborted: Could not create SSL/TLS secure channel" exception can occur if the server is returning an HTTP 401 Unauthorized response to the HTTP request.

You can determine if this is happening by turning on trace-level System.Net logging for your client application, as described in this answer.

Once that logging configuration is in place, run the application and reproduce the error, then look in the logging output for a line like this:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.

In my situation, I was failing to set a particular cookie that the server was expecting, leading to the server responding to the request with the 401 error, which in turn led to the "Could not create SSL/TLS secure channel" exception.

Upvotes: 15

Bryan Legend
Bryan Legend

Reputation: 6896

I had this problem trying to hit https://ct.mob0.com/Styles/Fun.png, which is an image distributed by CloudFlare on its CDN that supports crazy stuff like SPDY and weird redirect SSL certs.

Instead of specifying Ssl3 as in Simons answer I was able to fix it by going down to Tls12 like this:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");

Upvotes: 46

siddharth Jain
siddharth Jain

Reputation: 187

I have been getting the same error on a .NET 4.5.2 Winform application on a Windows 2008 Server.

I tried the following fix:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls1|SecurityProtocolType.Tls11| SecurityProtocolType.Tls12;

But that didnt work and the number of occurences of the error were still there.

As per one of the answers above, Is it mandatory to override the SchUseStrongCrypto key to the registry. Are there any side effects if i set this key.

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

Upvotes: 0

Arun Prasad E S
Arun Prasad E S

Reputation: 10135

This one is working for me in MVC webclient

public string DownloadSite(string RefinedLink)
{
    try
    {
        Uri address = new Uri(RefinedLink);

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

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

        using (WebClient webClient = new WebClient())
        {
            var stream = webClient.OpenRead(address);
            using (StreamReader sr = new StreamReader(stream))
            {
                var page = sr.ReadToEnd();

                return page;
            }
        }

    }
    catch (Exception e)
    {
        log.Error("DownloadSite - error Lin = " + RefinedLink, e);
        return null;
    }
}

Upvotes: 15

hogarth45
hogarth45

Reputation: 3677

Make sure the ServicePointManager settings are made before the HttpWebRequest is created, else it will not work.

Works:

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

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")

Fails:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")

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

Upvotes: 205

sina alizadeh
sina alizadeh

Reputation: 161

none of this answer not working for me , the google chrome and postman work and handshake the server but ie and .net not working. in google chrome in security tab > connection show that encrypted and authenticated using ECDHE_RSA with P-256 and AES_256_GCM cipher suite to handshake with the server.

enter image description here

i install IIS Crypto and in cipher suites list on windows server 2012 R2 ican't find ECDHE_RSA with P-256 and AES_256_GCM cipher suite. then i update windows to the last version but the problem not solve. finally after searches i understood that windows server 2012 R2 not support GSM correctly and update my server to windows server 2016 and my problem solved.

Upvotes: 8

Related Questions