-
由裸数据传输的 HTTP 协议转成加密数据传输的 HTTPS 协议,给应用数据套了个「保护伞」,提高安全性的同时也带来了性能消耗。
-
HTTPS 相比 HTTP 协议多一个 TLS 协议握手过程,目的是为了通过非对称加密握手协商或者交换出对称加密密钥
-
分析性能损耗
-
产生性能消耗的两个环节:
-
第一个环节, TLS 协议握手过程;
-
第二个环节,握手后的对称加密报文传输。
-
-
对于第二环节,现在主流的对称加密算法 AES、ChaCha20 性能都是不错的
-
第一个环节,TLS 协议握手过程不仅增加了网络延时(最长可以花费掉 2 RTT),而且握手过程中的一些步骤也会产生性能损耗
-
-
硬件优化
-
HTTPS 协议是计算密集型,而不是 I/O 密集型,所以不能把钱花在网卡、硬盘等地方,应该花在 CPU 上。
-
如果可以,应该选择可以支持 AES-NI 特性的 CPU,因为这种款式的 CPU 能在指令级别优化了 AES 算法,这样便加速了数据的加解密传输过程。
-
-
软件优化
-
软件的优化方向可以分成两种,一个是软件升级,一个是协议优化。
-
软件升级,软件升级就是将正在使用的软件升级到最新版本,因为最新版本不仅提供了最新的特性,也优化了以前软件的问题或性能
-
-
-
协议优化
-
对「密钥交换过程」进行优化
-
密钥交换算法优化
-
RSA 密钥交换算法的 TLS 握手过程,不仅慢,而且安全性也不高
-
尽量选用 ECDHE 密钥交换算法替换 RSA 算法,因为该算法由于支持「False Start」,它是“抢跑”的意思,客户端可以在 TLS 协议的第 3 次握手后,第 4 次握手前,发送加密的应用数据,以此将 TLS 握手的消息往返由 2 RTT 减少到 1 RTT,而且安全性也高,具备前向安全性。
-
ECDHE 算法是基于椭圆曲线实现的,不同的椭圆曲线性能也不同,应该尽量选择 x25519 曲线,该曲线是目前最快的椭圆曲线。
-
对于对称加密算法方面,如果对安全性不是特别高的要求,可以选用 AES_128_GCM,它比 AES_256_GCM 快一些,因为密钥的长度短一些。
-
-
-
TLS升级
-
如果可以,直接把 TLS 1.2 升级成 TLS 1.3,TLS 1.3 大幅度简化了握手的步骤,完成 TLS 握手只要 1 RTT,而且安全性更高。
-
TLS1.3 对密码套件进行“减肥”了, 对于密钥交换算法,废除了不支持前向安全性的 RSA 和 DH 算法,只支持 ECDHE 算法。
-
-
证书优化
-
为了验证的服务器的身份,服务器会在 TLS 握手过程中,把自己的证书发给客户端,以此证明自己身份是可信的。
-
对于证书的优化,可以有两个方向:
-
一个是证书传输
-
一个是证书验证
-
-
证书传输优化
-
对于服务器的证书应该选择椭圆曲线(ECDSA)证书,而不是 RSA 证书,因为在相同安全强度下, ECC 密钥长度比 RSA 短的多。
-
-
证书验证优化
-
CRL
-
CRL 称为证书吊销列表(Certificate Revocation List),这个列表是由 CA 定期更新,列表内容都是被撤销信任的证书序号,如果服务器的证书在此列表,就认为证书已经失效,不在的话,则认为证书是有效的。
-
CRL 存在两个问题:
-
第一个问题,由于 CRL 列表是由 CA 维护的,定期更新,如果一个证书刚被吊销后,客户端在更新 CRL 之前还是会信任这个证书,实时性较差;
-
第二个问题,随着吊销证书的增多,列表会越来越大,下载的速度就会越慢,下载完客户端还得遍历这么大的列表,那么就会导致客户端在校验证书这一环节的延时很大,进而拖慢了 HTTPS 连接。
-
-
-
OCSP
-
现在基本都是使用 OCSP ,名为在线证书状态协议(Online Certificate Status Protocol)来查询证书的有效性,它的工作方式是向 CA 发送查询请求,让 CA 返回证书的有效状态。
-
OCSP 需要向 CA 查询,因此也是要发生网络请求,而且还得看 CA 服务器的“脸色”,如果网络状态不好,或者 CA 服务器繁忙,也会导致客户端在校验证书这一环节的延时变大
-
-
OCSP Stapling
-
为了解决这一个网络开销,就出现了 OCSP Stapling,其原理是:服务器向 CA 周期性地查询证书状态,获得一个带有时间戳和签名的响应结果并缓存它。
-
-
-
-
会话复用
-
TLS 握手为了协商出会话密钥,也就是对称加密密钥,那我们如果我们把首次 TLS 握手协商的对称加密密钥缓存起来,待下次需要建立 HTTPS 连接时,直接「复用」这个密钥,不就减少 TLS 握手的性能损耗了吗?
-
会话复用分两种
-
第一种叫 Session ID
-
第二种叫 Session Ticket
-
-
Session ID
-
客户端和服务器首次 TLS 握手连接后,双方会在内存缓存会话密钥,并用唯一的 Session ID 来标识,Session ID 和会话密钥相当于 key-value 的关系。
-
有两个缺点:
-
服务器必须保持每一个客户端的会话密钥,随着客户端的增多,服务器的内存压力也会越大
-
现在网站服务一般是由多台服务器通过负载均衡提供服务的,客户端再次连接不一定会命中上次访问过的服务器,于是还要走完整的 TLS 握手过程
-
-
-
Session Ticket
-
服务器不再缓存每个客户端的会话密钥,而是把缓存的工作交给了客户端
-
客户端与服务器首次建立连接时,服务器会加密「会话密钥」作为 Ticket 发给客户端,交给客户端缓存该 Ticket。
-
对于集群服务器的话,要确保每台服务器加密 「会话密钥」的密钥是一致的
-
Session ID 和 Session Ticket 都不具备前向安全性,因为一旦加密「会话密钥」的密钥被破解或者服务器泄漏「会话密钥」,前面劫持的通信密文都会被破解。
-
重放攻击(可能会出现的问题)
-
解决的方法:对会话密钥设定一个合理的过期时间
-
-
-
Pre-shared Key
-
前面的 Session ID 和 Session Ticket 方式都需要在 1 RTT 才能恢复会话。
-
而 TLS1.3 更为牛逼,对于重连 TLS1.3 只需要 0 RTT,原理和 Ticket 类似,只不过在重连时,客户端会把 Ticket 和 HTTP 请求一同发送给服务端,这种方式叫 Pre-shared Key。
-
Pre-shared Key 也有重放攻击的危险。
-
解决方法:应对 重放攻击 可以给会话密钥设定一个合理的过期时间,以及只针对安全的 HTTP 请求如 GET/HEAD 使用会话重用
-
-