System.Net.WebRequest 支持哪些版本的 SSL/TLS?

Posted

技术标签:

【中文标题】System.Net.WebRequest 支持哪些版本的 SSL/TLS?【英文标题】:Which versions of SSL/TLS does System.Net.WebRequest support? 【发布时间】:2014-12-12 09:52:50 【问题描述】:

现在发现 SSL 3 容易受到POODLE 攻击:

System.Net.WebRequest 在连接到任何 https Uri 时使用哪些版本的 SSL/TLS?

我使用 WebRequest 连接到多个第 3 方 API。其中之一现在表示他们将阻止任何使用 SSL 3 的请求。但 WebRequest 是 .Net 核心框架(使用 4.5)的一部分,因此它使用的版本并不明显。

【问题讨论】:

如果服务器(或中间人)请求 WebRequest 是否会回退到 SSL 3? 如果我没记错的话,我认为 WebRequest 会查看您尝试提取的服务器上的安全证书,并使用 Web 服务器上的任何加密模式。我认为您不需要在客户端进行任何更改。 我希望刚刚表示不支持 SSL3 的 API 所有者考虑过确保他们的服务器不要求客户端使用 SSL3 :) @iceman 有什么方法可以从证书中判断它是否支持 SSL3?我没有看到任何与版本相关的属性。 @JK。 - 我不确定其他浏览器,但我使用的是 Chrome。在 Chrome 中,如果您访问 HTTPS 网站(例如 Wellsfargo.com),您会在 URL 附近看到一个绿色锁。单击该锁,然后单击连接选项卡,它会显示给您。对于 wellsfargo.com,Chrome 显示“连接使用 TLS 1.0”。 IE 和其他浏览器应该显示相同的类似内容。 【参考方案1】:

这是一个重要的问题。 SSL 3 协议 (1996) 被 2014 年发布的 Poodle 攻击无法挽回地破坏。IETF 发布了"SSLv3 MUST NOT be used"。网络浏览器正在抛弃它。 Mozilla Firefox 和 Google Chrome 已经这样做了。

在浏览器中检查协议支持的两个优秀工具是 SSL Lab's client test 和 https://www.howsmyssl.com/ 。后者不需要javascript,所以你可以从.NET的HttpClient试试:

// set proxy if you need to
// WebRequest.DefaultWebProxy = new WebProxy("http://localhost:3128");

File.WriteAllText("howsmyssl-httpclient.html", new HttpClient().GetStringAsync("https://www.howsmyssl.com").Result);

// alternative using WebClient for older framework versions
// new WebClient().DownloadFile("https://www.howsmyssl.com/", "howsmyssl-webclient.html");

结果很糟糕:

您的客户端使用的是非常旧的 TLS 1.0,可能容易受到 BEAST 攻击,并且没有可用的最佳密码套件。 TLS 1.0 客户端以及更多现代密码套件无法使用 AES-GCM 和 SHA256 等替代 MD5-SHA-1 的附加功能。

这令人担忧。它与 2006 年的 Internet Explorer 7 相当。

要准确列出 HTTP 客户端支持的协议,您可以尝试以下特定于版本的测试服务器:

var test_servers = new Dictionary<string, string>();
test_servers["SSL 2"] = "https://www.ssllabs.com:10200";
test_servers["SSL 3"] = "https://www.ssllabs.com:10300";
test_servers["TLS 1.0"] = "https://www.ssllabs.com:10301";
test_servers["TLS 1.1"] = "https://www.ssllabs.com:10302";
test_servers["TLS 1.2"] = "https://www.ssllabs.com:10303";

var supported = new Func<string, bool>(url =>

    try  return new HttpClient().GetAsync(url).Result.IsSuccessStatusCode; 
    catch  return false; 
);

var supported_protocols = test_servers.Where(server => supported(server.Value));
Console.WriteLine(string.Join(", ", supported_protocols.Select(x => x.Key)));

我正在使用 .NET Framework 4.6.2。我发现 HttpClient 只支持 SSL 3 和 TLS 1.0。这很令人担忧。这与 2006 年的 Internet Explorer 7 相当。


更新: HttpClient 确实支持 TLS 1.1 和 1.2,但您必须在 System.Net.ServicePointManager.SecurityProtocol 手动打开它们。见https://***.com/a/26392698/284795

我不知道为什么它使用坏的开箱即用协议。这似乎是一个糟糕的设置选择,相当于一个重大的安全漏洞(我敢打赌,很多应用程序都不会更改默认设置)。我们如何举报?

【讨论】:

哪个协议 我必须使用 有没有测试TLS1.3的服务器?【参考方案2】:

使用 System.Net.WebRequest 时,您的应用程序将与服务器协商以确定您的应用程序和服务器都支持的最高 TLS 版本,并使用它。您可以在此处查看有关其工作原理的更多详细信息:

http://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake

如果服务器不支持 TLS,它将回退到 SSL,因此它可能会回退到 SSL3。您可以在此处查看 .NET 4.5 支持的所有版本:

http://msdn.microsoft.com/en-us/library/system.security.authentication.sslprotocols(v=vs.110).aspx

为了防止您的应用程序容易受到 POODLE 的攻击,您可以按照以下说明在运行您的应用程序的机器上禁用 SSL3:

https://serverfault.com/questions/637207/on-iis-how-do-i-patch-the-ssl-3-0-poodle-vulnerability-cve-2014-3566

【讨论】:

我建议要使 WebRequest 和 HttpWebRequest 等 出站 请求安全,您应该按照我在***.com/questions/26389899/… 的问题中详细说明的步骤禁用 SSL 回退。基本上你首先运行这行代码:System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Tls11 | SecurityProtocolType.Tls12; 据我了解,此答案中详述的注册表修复仅适用于入站连接。 请注意,在 .net framework 3.5 或更低版本中,您只能选择 SecurityProtocolType.Tls(因此是 TLS 1.0) 我能否通过放弃 System.Net.WebRequest 并使用其他库(例如 RestSharp)来获得更高的 TLS 支持,或者它是需要升级的实际 .net 框架吗? 我相信这是需要升级的实际.net框架。 www.passionatecoder.ca @JamesWestgate 我的印象是TLS 实际上会在操作系统/机器级别实现?那不是发生实际 HTTP 流量的地方吗?因此,我认为尝试告诉您的代码使用真正由操作系统确定的特定 TLS 是没有意义的。【参考方案3】:

我也在那里给出了答案,但文章@Colonel Panic 的更新指的是建议强制使用 TLS 1.2。将来,当 TLS 1.2 受到威胁或刚刚被取代时,将您的代码粘在 TLS 1.2 上将被视为缺陷。 .Net 4.6 默认启用与 TLS1.2 的协商。如果您可以选择将源升级到 .Net 4.6,我强烈建议您更改强制 TLS 1.2。

如果您确实强制使用 TLS 1.2,强烈考虑留下某种类型的面包屑,以便在您升级到 4.6 或更高版本的框架时消除这种强制。

【讨论】:

“.Net 4.6 默认启用与 TLS1.2 的协商”你有这方面的文档吗? 当时,我们发现了暗示此功能的不确定文档(请参阅示例上方的msdn.microsoft.com/en-us/library/…)。但是,我们通过使用锁定到 TLS 1.2 的服务器创建测试程序并使用 webrequest 尝试下载页面来验证这一点。然后我们更改了程序的框架版本。所有下层版本都无法连接,但.Net 4.6 连接没有问题。 感谢您提供详细信息,我看到很多 API 提供商指出 4.5 未连接到 TLS 1.2,但我努力提供任何官方文档,不得不依赖社区 :) 这是正确的,也是要走的路。我们有许多旧服务器与现在坚持使用 TLS 的 Web 端点通信。 Web 服务引用开始失败并出现 SSL/TLS 错误。您可以破解注册表,但将服务器升级到最新的 .NET 版本更容易、更安全。

以上是关于System.Net.WebRequest 支持哪些版本的 SSL/TLS?的主要内容,如果未能解决你的问题,请参考以下文章

获取访问IP,程序池访问,非局域网IP地址

c# 视频下载

C# HttpWebRequest 绝技

HTTPHelper

asp 中有没有 httpwebrequest

HttpRequest 和HttpWebRequest的区别