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

JK.*_*JK. 77 c# ssl webrequest .net-4.5 poodle-attack

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

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

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

Col*_*nic 49

这是一个重要的问题.SSL 3协议(1996)被2014年发布的Poodle攻击无法挽回.IETF发布了"不得使用SSLv3".Web浏览器正在放弃它.Mozilla Firefox谷歌Chrome已经这样做了.

用于检查浏览器中协议支持的两个优秀工具是SSL Lab的客户端测试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");
Run Code Online (Sandbox Code Playgroud)

结果是该死的:

您的客户端正在使用TLS 1.0,它很老,可能容易受到BEAST攻击,并且没有可用的最佳密码套件.用于替换MD5-SHA-1的AES-GCM和SHA256等附加功能不适用于TLS 1.0客户端以及更多现代密码套件.

这是令人担忧的.它与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)));
Run Code Online (Sandbox Code Playgroud)

我正在使用.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.请参阅/sf/answers/1847488891/

我不知道它为什么会使用开箱即用的坏协议.这似乎是一个糟糕的设置选择,相当于一个主要的安全漏洞(我打赌大量的应用程序不会改变默认值).我们怎么报告呢?


小智 48

使用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这样的*outbound*请求是安全的,你应该按照我在http://stackoverflow.com/questions/26389899/how-do-i-disable-的问题中详细说明的步骤来禁用SSL回退. SSL的回退和使用的仅-TLS换出站连接 - 在网.基本上你首先运行这行代码:**System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;**据我了解,此答案中详述的注册表修复程序仅适用于入站连接. (17认同)

Pro*_*gle 8

我也在那里给出答案,但文章@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的协商"你有这方面的文档吗? (2认同)
  • 当时,我们发现了暗示此功能的不确定文档(请参阅https://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx例子).但是,我们通过创建一个测试程序来验证这一点,该服务器被锁定到TLS 1.2并使用webrequest尝试下载页面.然后我们在程序上更改了框架版本.所有下层版本都无法连接,但.Net 4.6连接没有问题. (2认同)