Jay Metro
Jay Metro

Reputation: 31

HTTP Web Request TLS 1.3 with C# .NET Core 3.1 exception "The client and server cannot communicate, because they do not possess a common algorithm."

When attempting a web request to a site which requires TLS 1.3 https://shop.claytonengineering.com/. I'm receiving the following exception on "request.GetResponse();".

Exception: The SSL connection could not be established, see inner exception. Inner Exception: The client and server cannot communicate, because they do not possess a common algorithm.

From Google Chrome Developer tools Security tab - "The connection to this site is encrypted and authenticated using TLS 1.3, X25519, and AES_128_GCM."

Any ideas on how to get this request to work?

HttpWebResponse response = null;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://shop.claytonengineering.com/");

request.KeepAlive = true;
request.Headers.Add("Upgrade-Insecure-Requests", @"1");
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36";
request.Headers.Add("Sec-Fetch-Mode", @"navigate");
request.Headers.Add("Sec-Fetch-User", @"?1");
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3";
request.Headers.Add("Sec-Fetch-Site", @"same-origin");

request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.9");

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;

response = (HttpWebResponse)request.GetResponse();

string html = null;

using (StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
    html = stream.ReadToEnd();
}

Upvotes: 3

Views: 5475

Answers (2)

Kalix
Kalix

Reputation: 39

I had this very same issue and found out that while .Net framework 4.8 and .Net5.0 and 6.0 all have implementations of the TLS1.3 stack, none of them seem to use them when you do not tell Windows to do so.

In my case I had to add the following registry key:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

For some reason these are not there by default.

Upvotes: 1

Matt Small
Matt Small

Reputation: 2275

There are at least two parts to a successful TLS connection:

  1. Protocol version
  2. Ciphersuite match

In both cases both the client and server must match up to use the same protocol and cipher. You already understand that there are multiple TLS versions (1.0, 1.1, 1.2, 1.3) but there are also multiple ciphers that are used to encrypt/decrypt information.

After the 3-way handshake, the client sends its accepted versions in the "Client Hello" and a list of accepted ciphers to the server. The server finds a match and sends that information back to the client ("Server Hello"), then communication begins.

In this case, although you're both using TLS 1.3, you aren't matching up with a cipher. The server has a list of ciphers that can be found by using the test found at ssllabs.com.

The list of ciphers accepted by the server you listed above is in the image below. You can enable one of the above on your client and then the connection should succeed. I assume you're using Windows, so please see this:

https://www.howtogeek.com/221080/how-to-update-your-windows-server-cipher-suite-for-better-security/#:~:text=On%20the%20left%20hand%20side%2C%20expand%20Computer%20Configuration%2C,%E2%80%9CEnabled%E2%80%9D%20button%20to%20edit%20your%20server%E2%80%99s%20Cipher%20Suites.

enter image description here

Upvotes: 3

Related Questions