一.介绍
这个问题还是挺少见的,因为触发的条件是.Net编写的程序访问的HTTPS网站开启了TLS1.2 Only,这就禁止了客户端和服务端协商后降级的情况,因而最终导致了无法访问。
二.进一步分析
列举一下条件
1. 程序使用.Net语言开发
2. 目标.Net框架版本为4.0以下
3. 目标客户端未安装微软的可选补丁
4. 使用 HttpClient 或者 WebClient 来访问接口(网站)
5. 接口使用HTTPS且强制TLS1.2
在如上情况下,会无法访问接口
微软官方补丁如下
* KB3154518 – Reliability Rollup HR-1605 – NDP 2.0 SP2 – Win7 SP1/Win 2008 R2 SP1
* KB3154519 – Reliability Rollup HR-1605 – NDP 2.0 SP2 – Win8 RTM/Win 2012 RTM
* KB3154520 – Reliability Rollup HR-1605 – NDP 2.0 SP2 – Win8.1RTM/Win 2012 R2 RTM
* KB3156421 -1605 HotFix Rollup through Windows Update for Windows 10.
三.解决
关于修复的话,其实比较烦人,或者说比较复杂,因为有多种选择
1. 使用第三方库来替代官方的方法
2. 让客户去把补丁装了
3. 更改目标框架为4.6+,然后让客户去装新版本的.Net
4. 将目标框架升到4.0+然后让客户同时装4.0和4.5+的框架,同时修改代码添加TLS1.2(具体参见下方,如果不添加的话需要客户修改注册表来将默认协议改成TLS1.2
5. 为接口做个支持其他协议的反代地址
我个人对.Net不算熟悉,不知道有啥库能不依赖官方环境来实现TLS1.2的客户端,所以这个排除
让客户装补丁这个比较头疼,因为微软这萨比把这补丁作为可选的了,在不强推的情况下我觉得根本没人会去装,所以基本凉凉,只能作为参考方案
更改目标框架也许是最好的解决办法,毫不妥协,但是……也没那么好办到,因为会出现,用户找不到哪儿能下,用户不想下载并向你吐了个槽的情况
这个混合方案的话也有上面的问题,很蛋疼
反代也许是最无需干预的解决办法,除非你完全不想屌用户并且坚持TLS1.2 Only,不然我推荐这么搞
这儿引用网上的一个说明
1. .NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
4.6直接默认TLS1.2了,所以无需修改啥,只是版本太新很多人可能都没装
2. .NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12不像下面那个,这儿4.5版本已经对TLS1.2增加了定义,所以可以直接指定,如果需要添加降级的情况,可以用竖线分隔多个`SecurityProtocolType`
3. .NET 4.0. TLS 1.2 is not supported, but if you have .NET 4.5 (or above) installed on the system then you still can opt in for TLS 1.2 even if your application framework doesn’t support it. The only problem is that SecurityProtocolType in .NET 4.0 doesn’t have an entry for TLS1.2, so we’d have to use a numerical representation of this enum value:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;这儿是4.0为目标框架并且用户安装了4.5或以上的版本的情况,由于TLS1.2未在4.0中定义,所以必须采用这种方法才能使用
4. .NET 3.5 or below. TLS 1.2 is not supported (*) and there is no workaround. Upgrade your application to more recent version of the framework.
.NET 3.5这个由于微软的补丁所以不算是无可救药的了,不过我建议不要寄希望于你的用户
下面是我参考的内容
1. https://blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support/
这篇建议看下评论,有MSFT的员工对补丁做了说明
2. https://stackoverflow.com/questions/22251689/make-https-call-using-httpclient
3. https://stackoverflow.com/questions/28286086/default-securityprotocol-in-net-4-5
文章评论