本站支持 TLSv 1.3

科普 TLS 1.3

TLS 1.3 协议针对安全强化及效率提升等方面进行了大量修改,相继推出20多个草案版本,即将完成最终的标准化。完成后,OpenSSL组织将推出OpenSSL 1.1.1 版本对 TLS1.3 协议标准提供支持。

本文主要讲解 TLS 1.3 版本的相关特性以及如何在你的服务器上启用 TLS 1.3 的支持。

在谈 TLS 1.3 之前,我们先来看下 TLS 1.2 的工作模式,如图所示是 TLS 1.2 客户端和服务端交互的过程,如图所示:

我们也可以通过 Wireshark 抓包得到的数据

以 ECDHE 密钥交换算法为例,TLS1.2协议完整的SSL握手过程如下:

  • 第一步,首先客户端发送ClientHello消息,该消息中主要包括客户端支持的协议版本、加密套件列表及握手过程需要用到的ECC扩展信息;
  • 第二步,服务端回复ServerHello,包含选定的加密套件和ECC扩展;发送证书给客户端;选用客户端提供的参数生成ECDH临时公钥,同时回复ServerKeyExchange消息;
  • 第三步,客户端接收ServerKeyExchange后,使用证书公钥进行签名验证,获取服务器端的ECDH临时公钥,生成会话所需要的共享密钥;生成ECDH临时公钥和ClientKeyExchange消息发送给服务端;
  • 第四步,服务器处理ClientKeyExchange消息,获取客户端ECDH临时公钥;服务器生成会话所需要的共享密钥;发送密钥协商完成消息给客户端;
  • 第五步,双方使用生成的共享密钥对消息加密传输,保证消息安全。

可以看到,TLS1.2 协议中需要加密套件协商、密钥信息交换、ChangeCipherSpec 协议通告等过程,需要消耗 2-RTT 的握手时间,这也是造成 HTTPS 协议慢的一个重要原因之一。

我们来看下 TLS 1.3 的的交互过程,如图所示:

其抓包得到的数据流如下:

在 TLS 1.3 中,客户端首先不仅发送 ClientHello 支持的密码列表,而且还猜测服务器将选择哪种密钥协商算法,并发送密钥共享,这可以节省很大一部分的开销,从而提高了速度。

TLS1.3 提供 1-RTT 的握手机制,还是以 ECDHE 密钥交换过程为例,握手过程如下。将客户端发送 ECDH 临时公钥的过程提前到 ClientHello ,同时删除了 ChangeCipherSpec 协议简化握手过程,使第一次握手时只需要1-RTT,来看具体的流程:

  • 客户端发送 ClientHello 消息,该消息主要包括客户端支持的协议版本、DH密钥交换参数列表KeyShare;
  • 服务端回复 ServerHello,包含选定的加密套件;发送证书给客户端;使用证书对应的私钥对握手消息签名,将结果发送给客户端;选用客户端提供的参数生成 ECDH 临时公钥,结合选定的 DH 参数计算出用于加密 HTTP 消息的共享密钥;服务端生成的临时公钥通过 KeyShare 消息发送给客户端;
  • 客户端接收到 KeyShare 消息后,使用证书公钥进行签名验证,获取服务器端的 ECDH 临时公钥,生成会话所需要的共享密钥;
  • 双方使用生成的共享密钥对消息加密传输,保证消息安全。

如果客户端之前已经连接,我们有办法在 1.2 中进行 1-RTT 连接,而在 TLS 1.3 中允许我们执行 0-RTT连接,如图所示:

需要说明的是,如需查看 TLS 1.3 的报文,需要使用 2.5 版本的wireshark,可以去 https://www.wireshark.org/download/automated/ 下载

TLS 1.3 的新特性

密钥交换

完全支持 PFS

TLS 1.3 协议中选取的密钥交换算法均支持前向安全性。斯诺登事件之后互联网企业开始重视加密算法的前向安全性,防止私钥被破解之后历史数据也能被解密成明文。

为了达到上述安全目的,TLS1.3 协议中废除了不支持前向安全性的RSA和静态DH密钥交换算法。

废弃 DSA 证书

DSA证书作为历史遗留产物,因安全性差,从未被大规模应用,故在 TLS1.3 协议中被废弃。

RSA 填充模式更改

协议中规定RSA填充模式使用PSS。

禁用自定义的 DH 组参数

如果选用了不“安全”的素数作为 DH 的组参数,并且使用静态DH密码套件或使用默认 OpenSSL 配置的DHE加密套件(特别是SSL_OP_SINGLE_DH_USE选项未设置),就很容易受到 Key Recovery Attack 攻击。 因此 TLS1.3 协议中禁用自定义的DH组参数。

对称加密

禁用 CBC 模式

针对 CBC 模式加密算法的攻击,历史上出现过两次,分别是 2011 年BEAST和2013年Lucky 13,实践证明这种对称加密模式确实存在安全隐患。

禁用 RC4 流加密算法

研究人员发现了 BEAST 攻击,该攻击针对所有基于 CBC 模式的加密算法。为解决这个问题,专家建议采用非CBC 模式且普及率较高的 RC4 算法作为替代方案,由此 RC4 算法得到广泛应用。

随着 TLS 版本的演进,BEAST 攻击可通过升级到新版本解决,不必要采用 RC4 这种陈旧算法来替代。另外,2013 年英国皇家哈洛威学院的研究人员发现了一种针对TLS的攻击,该攻击可以从 RC4 算法加密的密文中恢复出少量明文,证明了这种算法无法提供让人放心的安全等级。

为防止 RC4 算法被彻底破解,导致之前加密的网络流量被解密出现严重的安全事故,互联网公司逐渐废弃了这个算法。2014年,CloudFlare 将 RC4 算法的优先级从最高降为最低。2015 年,IETF 组织在 rfc7465 中明确指出要禁用 RC4 流加密算法。

禁用SHA1

大约在2015年 SHA1 就存在理论上的漏洞,可能造成碰撞攻击。

2013 年开始微软、Google、Symantec 等相关厂商相继公布 SHA1 证书的升级计划并宣布 2017 年将开始停止信任 SHA1 证书。

2017 年初 Google 与荷兰研究机构 CWI Amsterdam 共同宣布破解 SHA1,将 SHA1 的碰撞攻击从理论转变为现实。

禁用出口密码套件

出口密码套件是指上世纪 90 年代美国政府为让 NSA 能够破解所有加密的外国通讯消息,规定其出口的必须是安全性较弱的密码套件,例如私钥长度不大于 512 的 RSA 加密算法,这类加密套件被称为出口密码套件。在当时,安全等级较高的加密套件被是为战争武器禁止出口。

尽管 2000 年之后美国放宽了密码出口管制,但是由于历史遗留问题,许多实际场景中仍使用出口加密套件进行协商,导致 FREAK 和 LogJam 攻击的出现,这两种攻击通过中间人将加密套件降级成出口套件,进而将破解数据。

禁用 TLS 压缩

由于 TLS 压缩存在安全漏洞,TLS1.3 协议删除了该特性。

加密握手消息

TLS 1.3 协议中规定在 ServerHello 消息之后的握手信息需要加密。TLS1.2 及之前版本的协议中各种扩展信息在 ServerHello 中以明文方式发送,新版本中可在加密之后封装到 EncryptedExtension 消息中,在ServerHello 消息之后发送,提高数据安全性。

效率提升

对于互联网服务而言更快的页面加载意味着更好的用户体验,从而也能带动产品销售的提升。

HTTPS 在提高网络安全的同时却增加了额外的性能消耗,包括额外的 SSL 握手交互过程,数据加解密对 CPU 的消耗等。TLS 1.3 在提高效率方面进行了大量改进,特别是对 SSL 握手过程进行了重新设计,将握手交互延时从 2-RTT 降低至 1-RTT 甚至是 0-RTT。在网络环境较差或节点距离较远的情况下,这种优化能节省几百毫秒的时间。这几百毫秒往往就能决定用户下一步的行为是继续浏览网页还是关闭网页。

0-RTT模式不具有前向安全性,且消息可能被用作重放攻击,所以安全性较低,需慎重使用。

浏览器支持 TLS 1.3

目前最新版 Chrome 和 Firefox 都支持 TLS 1.3,但需要手动开启:

Chrome,将 chrome://flags/ 中的 Maximum TLS version enabled 改为 TLS 1.3(Chrome 62 中需要将 TLS 1.3 改为 Enabled (Draft)

Firefox,将 about:config 中的 security.tls.version.max 改为 4

Web 服务器支持 TLS 1.3

首先,需要下载 openssl 开发版,目前 TLS 1.3 还处于 draft 版,所以要克隆其分支进行编译。

git clone -b tls1.3-draft-18 --single-branch https://github.com/openssl/openssl.git openssl

注意: github 的最新版本 tls1.3-draft-19 编译后并不会有效果

以 nginx 1.13.8 为例(自 1.13.0 开始 nginx 开始支持 TLSv1.3),在编译的时候加上

--with-openssl=../openssl --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers'

例如我的编译参数

./configure --prefix=/usr/local/nginx --user=www --group=www --with-pcre=/opt/nginx/pcre-8.41 --with-http_ssl_module --with-zlib=/opt/nginx/zlib-1.2.11 --with-http_v2_module --add-module=../nginx-ct-1.3.2 --add-module=../ngx_brotli --with-openssl=../openssl --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module

编译完成停止你的 nginx 进程,在 nginx 目录执行如下命令

cp -rf  ./objs/nginx /usr/local/nginx/sbin/ 

在你的 nginx 配置文件中添加如下配置

ssl_protocols              TLSv1.2 TLSv1.3; #增加 TLSv1.3
ssl_ciphers                TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

重启 nginx 服务。

CDN 支持 TLS 1.3

目前又拍云已经率先支持 TLS 1.3,你可以在控制台开启

开启后通过浏览器访问可以看到协议版本