2.5.1 理解 HTTPS 流程
HTTPS 流程中涉及了证书、CA、TLS、对称/非对称加密等繁杂的环节。为了理解 HTTPS 完整的逻辑脉络,我们尝试从零开始设计一个“绝对”安全的信息传输机制,以理解 HTTPS 为何有这么多环节。
1. 解决信息传递的安全性
首先,HTTP 添加 SSL 层的本质是为了实现信息传递“绝对”的安全性。如图 2-12 所示,如果是一个 1 v 1 的通信模型,想实现信息传递安全性,使用对称加密就可以。只要保证密钥的安全,不让第三者知道,信息安全的问题就能解决!
图2-12 对称加密示例
对称加密方式在 HTTP 服务场景下就出现问题了,如图 2-13 所示。对称加密的关键操作是如何保证秘钥的安全性,而 HTTP 通信模型是 1 v N,使用对称加密这种方式等同没有加密。
图2-13 对称加密 1v N 模式
为了解决使用一个秘钥暴露的问题,我们尝试改进,使每个客户端使用不同的算法/密钥,并在增加一个协商的过程,用于双方协商采用何种对称加密算法/密钥(这个协商的过程就是 TLS 协议做的事情),流程如图 2-14 所示。
图2-14 对称加密模式下密钥协商过程
不过问题还是存在,虽然协商过程解决了对称加密算法或秘钥独立性问题,但协商过程依旧是明文的,密钥仍然存在被截获的可能性。为了解决这个问题,只能继续对协商过程的数据进行加密。这个环节必须换一种思路,如果仍然采用对称加密方式,就会产生无限套娃的情况。
我们引入一个新的概念:非对称加密算法。
tip 非对称加密
非对称加密有两个密钥:公钥、私钥,私钥加密的密文只能公钥解,公钥加密的密文只能私钥解。
这里我们提一个既要又要的要求:”即要降低加解密的耗时,又要保证密钥传输的安全性“。由于对称加解密效率远比非对称加解密效率高得多,所以我们对 HTTP 内容使用对称加密,对称加密的密钥则通过非对称加密得到。后续协商流程中,通过一个随机数确定对称加密算法/密钥,然后使用非对称加密算法的私钥对其加密,客户端用公钥解密后获得对称加密的密钥,再用该密钥解密 HTTP 内容,从而获得明文。
但问题还没有结束,公钥如何传输给客户端呢?
2.证书认证机构
如图 2-15 所示,虽然服务端可以直接发送公钥证书至客户端,但仍然无法避免中间被截获的可能性。这个时候,我们可以引入一个双方都信任的第三方机构,使用第三方机构的私钥将服务器公钥加密后传输给客户端,客户端再使用第三方公钥进行解密。虽然流程绕了些,但至少离我们的目标”绝对“安全又近了些。
图2-15 公钥存在被截获的可能性
这个双方都信任的机构就是 HTTPS 中的 CA(CA,Certificate Authority,证书认证机构)。HTTPS 中把公钥规范成数字证书的形式由 CA 签发(数字证书通常包含服务端公钥、持有者信息、CA 的信息以及过期信息等)。服务端向 CA 申请数字证书,再把数字证书下发给客户端。至于第三方 CA 公钥的问题,解决方案就是提前预装在系统内,这就是系统内根证书的由来。
至此,信息传递的”绝对“安全性目标基本得到实现。
3.证书验证链
客户端从服务端下载证书之后,需要根据本地的根证书校验是否合法,因为服务端向 CA 申请的证书一般不是最顶级的 CA 机构签发,而是由中间二级 CA 机构签发,所以还有一个证书信任链的验证环节。如图 2-16 所示,thebyte.com.cn 证书的层级有三级。
图2-16 CA 证书层次结构
这种三级层级关系的证书会先由本地根证书验证中间证书,验证通过后再用中间证书验证服务端证书,全部验证通过后,则表示服务器证书是可信任的。从整个流程来看,HTTPS 关键在于根证书的安全性,如果根证书被修改了,那么信息传递也不再是“绝对”安全。
理解了 HTTPS 的原理之后,我们继续下一节,看看 SSL 层有哪些可以优化的措施,以便让 HTTPS 请求更快。
2.5.2 SSL 层优化实践
HTTPS 建立连接的过程中,TLS 握手阶段最长可以花费 2-RTT,除去握手延迟外,SSL 层还有其他的一些隐形消耗,不做任何优化措施情况下,网络耗时和加解密耗时影响会让 HTTPS 连接效率比 HTTP 慢上几百毫秒,在高延迟网络环境下,HTTPS 延迟问题更加明显。
2.6.1 节中,已介绍 SSL 层的原理,从中总结,对于 SSL 层的优化,我们从两个环节入手:协议升级、证书优化。
1. 协议升级
优化 SSL 层,效果最为明显的方式是升级最新 TLS1.3 协议^1。TLS 1.3 协议放弃了安全性较低的加密功能的支持,并改进了 TLS 握手流程。TLS 1.3 协议中的 TLS 握手只需要一次 RTT 而不是两次,如果客户端复用之前连接,TLS 握手的往返次数可以为零,这使 HTTPS 连接更快,能显著减少延迟并改善用户体验。如图 2-17 所示,如果使用 TLS 1.2 需要两次往返( 2-RTT )才能完成握手,然后才能发送请求。
图2-17 TLS1.2 握手流程
相比 TLS1.2 协议,TLS 1.3 协议的握手时间减半,如图 2-18 所示。这意味着访问一个网站,使用 TLS 1.3 协议,会降低将近 100ms 的延时。
图2-18 TLS1.3 握手流程
2.证书优化
SSL 层中的证书验证也是一个比较耗时的环节:服务器需要把自己的证书链全发给客户端,客户端接收后再逐一验证。证书环节我们关注两个方面优化:证书传输优化 、 证书中非对称算法升级 。
2.1 证书传输优化
客户端验证证书过程中,需要判断证书是否被被撤销失效等,需要再去访问 CA 下载 CRL 或者 OCSP 数据,这又会产生 DNS 查询、建立连接、收发数据等一系列网络通信,增加多个 RTT。
OCSP stapling(Online Certificate Status Protocol stapling)是一种改进的证书状态确认方法,用于减轻证书吊销检查的负载和提高数据传输的私密性^2。OCSP stapling 将原本需要客户端实时发起的 OCSP 请求转嫁给服务端,服务端通过预先访问 CA 获取 OCSP 响应,然后在握手时随着证书一起发给客户端,免去了客户端连接 CA 服务器查询的环节。
- 在 Nginx 中配置 OCSP stapling 服务。
server { listen 443 ssl; server_name thebyte.com.cn; index index.html; ssl_certificate server.pem;#证书的.cer文件路径 ssl_certificate_key server-key.pem;#证书的.key文件 # 开启 OCSP Stapling 当客户端访问时 NginX 将去指定的证书中查找 OCSP 服务的地址,获得响应内容后通过证书链下发给客户端。 ssl_stapling on; ssl_stapling_verify on;# 启用OCSP响应验证,OCSP信息响应适用的证书 ssl_trusted_certificate /path/to/xxx.pem;# 若 ssl_certificate 指令指定了完整的证书链,则 ssl_trusted_certificate 可省略。 resolver 8.8.8.8 valid=60s;#添加resolver解析OSCP响应服务器的主机名,valid表示缓存。 resolver_timeout 2s;# resolver_timeout表示网络超时时间
- 检查服务端是否已开启 OCSP Stapling。
openssl s_client -connect thebyte.com.cn:443 -servername thebyte.com.cn -status -tlsextdebug < /dev/null 2>&1 | grep "OCSP"
若结果中存在”successful“,则表示已开启 OCSP Stapling 服务。
OCSP response: OCSP Response Data: OCSP Response Status: successful (0x0) Response Type: Basic OCSP Response
2.2 证书算法优化
目前 SSL 密钥交换 + 签名有三种主流的方式:
- RSA 密钥交换(无需签名)。
- ECDHE 密钥交换、RSA 签名。
- ECDHE 密钥交换、ECDSA 签名。
内置 ECDSA 公钥的证书一般被称之为 ECC 证书,内置 RSA 公钥的证书就是 RSA 证书,相比 RSA,ECC 证书具有安全性高,处理速度更快的优点,尤其适合在移动设备上使用。但是其唯一的缺点就是兼容性问题,古代的 XP 和 Android2.3 不支持这种加密方式。不过 Nginx 从 1.11.0 版本起开始提供了对 RSA/ECC 双证书的支持,它可以在 TLS 握手的时候根据客户端支持的加密方法选择对应的证书,以向下兼容古代客户端。
如图 2-19 所示,256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,加上 ECC 运算速度更快,ECDHE 密钥交换 + ECDSA 数字签名无疑是最好的选择。由于同等安全条件下,ECC 算法所需的 Key 更短,所以 ECC 证书文件体积比 RSA 证书要小一些。
图2-19 ECC vs RSA
在 Nginx 里可以用 ssl_ciphers、ssl_ecdh_curve 等指令配置服务器使用的密码套件和椭圆曲线,把优先使用的放在前面,配置示例:
ssl_dyn_rec_enable on; ssl_protocols TLSv1.2 TLSv1.3; ssl_ecdh_curve X25519:P-256; ssl_ciphers 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; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:20m; ssl_session_timeout 15m; ssl_session_tickets off;
配置完成之后,使用 https://myssl.com/ 服务测试证书配置,如图 2-20 所示。
图2-20 使用 myssl.com 测试证书
3.SSL 优化效果
SSL 层的优化手段除了软件层面还有一些硬件加速的方案,例如使用支持 AES-NI 特性的 CPU、专用 QAT 加速卡^3。如表 2-2,通过对 ECC、RSA、TLS1.2、TLS1.3 等不同维度的测试,以获取最佳的配置方案。
表 2-2 HTTPS 不同维度的性能测试
场景 | QPS | Time | 单次发出请求数 |
---|---|---|---|
RSA 证书 + TLS1.2 | 316.20 | 316.254ms | 100 |
RSA 证书 + TLS1.2 + QAT | 530.48 | 188.507ms | 100 |
RSA 证书 + TLS1.3 | 303.01 | 330.017ms | 100 |
RSA 证书 + TLS1.3 + QAT | 499.29 | 200.285ms | 100 |
ECC 证书 + TLS1.2 | 639.39 | 203.319ms | 100 |
ECC 证书 + TLS1.3 | 627.39 | 159.390ms | 100 |
从 SSL 加速的结果上看,使用 ECC 证书较 RSA 证书性能提升很多,即使 RSA 使用了 QAT 加速比起 ECC 还是存在差距。另外 QAT 方案的硬件成本、维护成本较高,综合考虑建议使用 TLS1.3 + ECC 证书方式。
^1: 参见 https://wiki.openssl.org/index.php/TLS1.3
^2: 参见 https://datatracker.ietf.org/doc/html/rfc6066#section-8
^3: 英特尔® Quick Assist Technology(简称 QAT)是 Intel 公司推出的一种专用硬件加速技术,可以用来提高 Web 服务器中计算密集的公钥加密以及数据压缩解压的吞吐率以及降低 CPU 负载。
添加评论