.NET CORE 5进行HTTPS请求时出现“握手失败(HandshakeFailure)”错误

9

有一个请求,在C#中无法正常工作(不管是使用RestClient还是HttpClient)。 当我尝试通过RestSharp连接到端点时,我获得StatusCode 0,而在HttpClient上,我则会遇到以下异常:

由于远程方发送了TLS警报:“握手失败”,因此身份验证失败。

有趣的是,Postman上这个请求却非常正常(是的,我尝试从Postman生成代码,但仍然无法正常工作)。

我查看了Postman并发现它使用TLS 1.2证书,然后我尝试了这个:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

但仍然没有任何效果。

检查了url、身份验证、标头、HTTP动词等,一切都很OK。

附注:我只能通过VPN访问这些端点,这是否有点奇怪呢?

检查Postman所使用的TLS版本

2个回答

20

我有类似的问题。在我的情况下,我的服务器的Windows版本太旧了。这些请求在我的更新到最新的Windows 10笔记本电脑上完全正常,但在我的Windows Server 2012 R2机器上会出现“握手失败”。

如果我理解正确的话,问题就在于您操作系统所支持的加密套件。(您可以在此处找到大多数Windows版本支持的所有加密套件列表:https://learn.microsoft.com/en-au/windows/win32/secauthn/cipher-suites-in-schannel)。

如果您的HTTPS网站使用的加密套件不受您的操作系统支持,.NET将抛出此错误。您可以使用像sslscanhttps://github.com/rbsec/sslscan)之类的工具,查找HTTPS端点支持的加密套件。

为什么Postman/Browsers可以正常工作?浏览器和其他工具都附带了自己的一组加密套件。这就是为什么这些工具不受此影响的原因。

不幸的是,除了更新您的Windows机器外,我没有其他解决方法。但我希望它能回答为什么不起作用的问题。

对于此问题,还有一种可能的解决方案,但只适用于您拥有请求域的情况。您可以“降级”用于该域的加密套件。


你知道为什么.NET Core要依赖于操作系统9年前提供的过时密码,而其他工具则提供自己的密码吗?似乎可以将其作为NuGet包添加以防止这种情况发生。 - priehl
我不知道为什么.NET在这些事情上要依赖操作系统。是的,我认为NuGet包可能是一个解决方案。 还有一种可能的解决方案:如果您拥有所请求的域名,您可以“降级”用于该域的密码。 - n-develop
答案提供了一种解决方案,使用另一个curl来获取数据。 - 我零0七

1

我知道有点晚了,但对于那些遇到同样问题的人,我建议使用Nartac的IISCrypto工具,可以在这里找到。

引用他们的网站:

IIS Crypto是一个免费工具,可让管理员在Windows Server 2008、2012、2016和2019上启用或禁用协议、密码、哈希和密钥交换算法。它还允许您重新排序IIS提供的SSL/TLS密码套件,更改高级设置,通过单击实现最佳实践,创建自定义模板并测试您的网站。

对于大多数情况,按下“最佳实践”按钮并重新启动即可。


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