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 服务器查询的环节。

  1. 在 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表示网络超时时间

 
  1. 检查服务端是否已开启 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 负载。


  • 无标签

0 评论

你还没有登录。你所做的任何更改会将作者标记为匿名用户。 如果你已经拥有帐户,请登录