使用C# .NET Core 3.1进行HTTP Web请求时出现TLS 1.3异常:“客户端和服务器无法通信,因为它们没有共同的算法。”

3
尝试向需要TLS 1.3的网站发送Web请求https://shop.claytonengineering.com/时,"request.GetResponse();"会出现以下异常:
异常:SSL连接无法建立,请参见内部异常。 内部异常:客户端和服务器无法通信,因为它们没有共同的算法。
从Google Chrome开发者工具安全选项卡中可以看到 - "连接到此站点使用TLS 1.3、X25519和AES_128_GCM进行加密和身份验证。"
有什么想法可以让这个请求工作吗?
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();
}
2个回答

3
至少有两个部分是构成成功的TLS连接的关键:
  1. 协议版本
  2. 密码套件匹配
在这两种情况下,客户端和服务器都必须匹配,使用相同的协议和密码。您已经了解到有多个TLS版本(1.0、1.1、1.2、1.3),但也有多个用于加密/解密信息的密码。
在三次握手之后,客户端在“客户端Hello”中发送其接受的版本以及接受的密码列表到服务器。服务器找到一个匹配项并将该信息发送回客户端(“服务器Hello”),然后通信开始。
在这种情况下,尽管您都在使用TLS 1.3,但您没有匹配密码。服务器有一个密码列表,可以通过在ssllabs.com上找到的测试来查找。
您列出的服务器接受的密码列表如下图所示。您可以在客户端上启用其中一个,然后连接应该会成功。我假设您正在使用Windows,请参见以下内容:
将Windows服务器的密码套件更新以提高安全性的方法:

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


1
确认Windows 10 Pro - 10.0.19043。 我还确认客户端安装了以下密码。这是服务器密码列表中列出的前两个密码。在将它们设置为密码套件顺序中的前两个后,网络请求仍然以相同的异常失败(并不意外)。 TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384。 对我来说,这似乎是.NET框架的一个漏洞。有什么想法吗? - Jay Metro
网络跟踪(wireshark)将告诉您客户端正在发送什么。我认为这不是.NET框架中的错误。此代码已经在生产中使用多年了。 - Matt Small

1
我曾经遇到过这个问题,并发现尽管 .Net framework 4.8、.Net5.0 和 6.0 都有 TLS1.3 栈的实现,但当你没有告诉 Windows 时,它们似乎都不会使用它们。
在我的情况下,我不得不添加以下注册表键:
[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

由于某些原因,默认情况下它们不存在。


你需要重新启动吗? - bob mason
您需要重新启动想要启用该进程的进程,而不需要重新启动整个机器。 - Kalix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接