@Eddie Loeffen的答案似乎是这个问题中最受欢迎的答案,但它会产生一些不良的长期影响。如果您查看System.Net.ServicePointManager.SecurityProtocol的文档页面
这里,备注部分暗示协商阶段应该只涉及到此事(强制协议在未来也是不好的实践,因为TLS 1.2也将被破解)。但是,如果他们协商不了呢,我们就无法得到这个答案。
经过研究,发现在协商阶段需要使用ALPN协议才能获得TLS1.2。我们以此为起点,尝试使用更新版本的.NET Framework来确定支持的开始位置。我们发现.NET 4.5.2不支持协商到TLS 1.2,但.NET 4.6支持。
因此,即使强制使用TLS1.2现在可以完成工作,我建议您升级到.NET 4.6。由于这是2016年6月PCI DSS问题,时间紧迫,但新的框架是更好的答案。
更新:
根据评论,我构建了这个:
ServicePointManager.SecurityProtocol = 0;
foreach (SecurityProtocolType protocol in SecurityProtocolType.GetValues(typeof(SecurityProtocolType)))
{
switch (protocol)
{
case SecurityProtocolType.Ssl3:
case SecurityProtocolType.Tls:
case SecurityProtocolType.Tls11:
break;
default:
ServicePointManager.SecurityProtocol |= protocol;
break;
}
}
为了验证概念,我将SSL3和TLS1.2进行或运算,并运行代码以连接到仅支持TLS 1.0和TLS 1.2(1.1已禁用)的服务器。使用进行或运算的协议看起来可以正常连接。但如果改为SSL3和TLS 1.1,则无法连接。我的验证使用System.Net中的HttpWebRequest,并只调用GetResponse()。例如,我尝试过以下内容但失败了:
HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11;
request.GetResponse();
虽然这样做是有效的:
HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
request.GetResponse();
这种方法的优点在于,与强制使用TLS 1.2相比,如果.NET Framework升级,枚举中有更多条目,它们将被支持并保持原样。与仅使用.NET 4.6相比,它的缺点在于4.6使用ALPN,如果未指定限制,则应支持新协议。
编辑于2019年4月29日 - Microsoft在去年发表了这篇文章。其中提供了对各个版本的.NET Framework如何进行推荐的概述。