如何针对老旧浏览器设置 HTTPS 策略(2)

Server Name Indication,简称为 SNI,是 TLS 的一个扩展,为解决这个问题应运而生。有了 SNI,服务端可以通过 Client Hello 中的 SNI 扩展拿到用户要访问网站的 Server Name,进而发送与之匹配的证书,顺利完成 SSL 握手。

Nginx 在很早之前就支持了 SNI,可以通过 nginx -V 来验证。以下是我的验证结果:

./nginx -V

nginx version: nginx/1.9.9

built by gcc4.8.4(Ubuntu4.8.4-2ubuntu1~14.04)

built withOpenSSL1.0.2e-dev xx XXX xxxx

TLS SNI support enabled

configure arguments:--with-openssl=../openssl --with-http_ssl_module --with-http_v2_module

然而,并不是所有浏览器都支持 SNI,以下是常见浏览器支持 SNI 的最低版本:

浏览器最低版本
Chrome   Vista+ 全支持;XP 需要 Chrome 6+;OSX 10.5.7+ 且 Chrome 5+  
Firefox   2.0+  
Internet Explorer   7+ (需要 Vista+)  
Safari   3+ (需要 OS X 10.5.6+)  
Mobile Safari   iOS 4.0+  
Android Webview   3.0+  

可以看到,现在还有一定用户量的 Windows XP IE6~8、Android 2.x Webview 都不支持 SNI。如果要避免在这些浏览器中出现证书错误,只能将使用不同证书的 HTTPS 站点部署在不同 IP 上,最简单的做法是分开部署到不同机器上。

证书选择

HTTPS 网站需要通过 CA 取得合法证书,证书通过数字签名技术确保第三方无法伪造。证书的简单原理如下:

根据版本号、序列号、签名算法标识、发行者名称、有效期、证书主体名、证书主体公钥信息、发行商唯一标识、主体唯一标识、扩展生成 TBSCertificate( 待签名证书(To Be Signed Certificate))信息;

签发数字签名:使用 HASH 函数对 TBSCertificate 计算得到消息摘要,用 CA 的私钥对消息摘要进行加密,得到签名;

校验数字签名:使用相同的 HASH 函数对 TBSCertificate 计算得到消息摘要,与使用 CA 公钥解密签名得到内容相比较;

使用 SHA-1 做为 HASH 函数的证书被称之为 SHA-1 证书,由于目前已经找到 SHA-1 的碰撞条件,将证书换成使用更安全的 SHA-2 做为 HASH 函数的 SHA-2 证书被提上日程。

实际上,微软已经宣称自 2017 年 1 月 1 日起,将全面停止对 SHA-1 证书的支持。届时在最新版本的 Windows 系统中,SHA-1 证书将不被信任。

而根据 Chrome 官方博客的文章,使用 SHA-1 证书且证书有效期在 2016 年 1 月 1 号至 2016 年 12 月 31 号之间的站点会被给予「安全的,但存在漏洞」的提示,也就是地址栏的小锁不再是绿色的,并且会有一个黄色小三角。而使用 SHA-1 证书且证书有效期超过 2017 年 1 月 1 号的站点会被给予「不安全」的红色警告,小锁上直接显示一个红色的叉。

然而,并不是所有的终端都支持 SHA-2 证书,服务端不支持还好办,浏览器只能依赖于用户升级了。下面是常见浏览器支持 SHA-2 证书的最低版本:

浏览器支持 SHA-2 证书的最低版本
Chrome   26+  
Firefox   1.5+  
Internet Explorer   6+ (需要 XP SP3+)  
Safari   3+ (需要 OS X 10.5+)  
Android Webview   2.3+  

可以看到,如果要照顾没有打 XP SP3 补丁的 IE6 用户,只能继续使用 SHA-1 证书。

在我之前的文章中,还提到过 ECC 证书,这种新型的证书支持度更差,这里略过不提,有兴趣的同学可以查看。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/16f10e2d3d83c9b271df473af7e73bdd.html