小林计网笔记-3.5 HTTPS如何优化?

HTTPS如何优化?

由裸数据传输的HTTP协议转成加密数据传输的HTTPS协议,给应用数据套了个保护伞,提高安全性的同时带来了性能消耗。
因为HTTPS相比HTTP协议多一个TLS协议握手过程,为了通过非对称加密握手协议或者交换出对称加密密钥,这个过程最长可以花费2RTT,接着后续传输的应用数据都得使用对称加密密钥来加密\解密。
为了数据的安全性,我们不得不使用HTTPS协议,至今大部分网址都已从HTTP迁移至HTTPS协议,因此针对HTTPS的优化是非常重要的。

分析性能损耗

产生性能消耗的两个环节:

  • 第一个环节:TLS协议握手过程
  • 第二个环节:握手后的对称加密报文传输

对于第二个环节,现在主流的对称加密算法AES、ChatCha20性能都是不错的,而且一些CPU产商针对它们做了硬件级别的优化,因此这个环节的性能消耗非常小。
而第一个环节,TLS协议握手过程不仅增加了网络延时(最长可以花费掉2RTT),而且握手过程中的一些步骤也会产生性能损耗,比如:

  • 对于ECHDE密钥协商算法,握手过程中客户端和服务端都需要临时生成椭圆曲线公私钥
  • 对于客户端验证证书时,会访问CA获取CRL或者OCSP,目的是验证服务器的证书是否有被吊销
  • 双方计算Pre-Master,也就是对称加密密钥
    在这里插入图片描述

硬件优化

HTTPS协议是计算密集型,而不是I/O密集型,所以应提升CPU性能,而不是网卡、硬盘等。
一个好的CPU,可以提高计算性能,因为HTTPS连接过程中有大量需要计算密钥的过程,所以这样可以加速TLS握手过程。
如果可以,选择支持AES-NI特性的CPU,因为这种款式的CPU能在指令级别优化AES算法,加速数据的加解密传输过程。
Linux系统,可以使用下面命令行查看CPU是否支持AES-NI指令集

$ sort -u /proc/cryto|grep module|grep aes module:aesni_intel

如果CPU支持AES-NI特性,则对称加密算法使用AES算法,否则可以选择ChatCha20对称加密算法,因为ChatCha20算法的运算指令相比AES算法会对CPU更友好一点。

软件优化

软件的优化方向可分为软件升级协议优化
软件升级就是正在使用的软件升级到最新版本,最新版本不仅提供最新的特性,也优化了以前软件的问题或性能。

  • 将Linux内核从2.x升级到4.x
  • 将OpenSSL从1.0.1升级到1.1.1
  • ……

实行软件升级,会花费时间和人力,同时也存在一定的风险,也可能会影响正常的线上服务。协议优化,在现有的环节下,通过较小的改动,来进行优化。

协议优化

协议的优化就是对【密钥交换过程】进行优化。

密钥交换算法优化

TLS1.2版本如果使用RSA密钥交换算法,那么需要4次握手,花费2RTT,才可以进行应用数据的传输,而且RSA密钥交换算法不具备前向安全性。RAS密钥交换算法的TLS握手过程,不仅慢,而且安全性也不高
尽量使用ECDHE密钥交换算法替换RSA算法,该算法支持[False Start],“抢跑”,客户端可以在TLS协议的第3次握手后,第4次握手前,发送加密的应用数据,以此将TLS握手的消息往返由2RTT减少到1RTT,而却安全性也高,具备前向安全性
ECDHE算法基于椭圆曲线实现的,不同的椭圆曲线性能也不同,应该尽量选择x25519曲线,该曲线是目前最快的椭圆曲线。
在Ngnix上,可以使用ssl_ecdh_curve指令配置向使用的椭圆曲线,把优先使用的放在最前面:

ssl_ecdh_curve X25519:secp384r1;

对称加密算法,如果对安全性不是特别搞得要求,可以选用ASE_128_GCM,它比ASE_256_GCM快一些,因为密钥的长度短一些
在Ngnix上,可以使用ssl_ciphers指令配置想使用的非对称加密算法和对称加密算法,密钥套件,而且把性能最快最安全的算法放在最前面:

ssl_ciphers 'EECEH+ECDSA+ASE128+SHA:RSA+ASE128+SHA'
TLS升级

将TLS 1.2升级成TLS 1.3,TLS 1.3大幅度简化了握手地步骤,完成TLS握手只要1RTT,而且安全性更高。
在TLS 1.2的握手中,一般需要4次握手,先要通过Cilent Hello(第一次握手)和Server Hello(第二次握手)消息协商出后续使用的加密算法,再互相交换公钥(第三次和第四次握手),然后计算出最终的会话密钥,下图左边就是TLS1.2的握手过程:
在这里插入图片描述
上图右边是TLS1.3的握手过程,TLS1.3把Hello和公钥交换这两个消息合并成了一个消息,减少到只需1RTT就能完成TLS握手
客户端在Client Hello消息里带上了支持的椭圆曲线,以及这些椭圆曲线对应的公钥。服务端收到后,选用一个椭圆曲线等参数,然后返回消息时,带上服务器的公钥。经过1RTT,双方都已有生成会话密钥的材料,于是客户端计算出会话密钥,就可以进行应用数据的加密传输。
TLS1.3对密码套件进行减肥了,对于密钥交换算法,废除了不支持前向安全性的RSA和DH算法,只支持ECDHE算法
对于对称加密和签名算法,只支持目前最安全的几个密码套件,比如openssl中仅支持下面5种密码套件:

  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256

TLS1.2由于支持各种古老且不安全的密码套件,中间人可以利用降级攻击,伪造客户端的Client Hello消息,替换客户端支持的密码套件的一些不安全的密码套件,使得服务器被迫使使用这个密码套件进行HTTPS连接,从而破解密文。

证书优化

为了验证服务器身份,服务器会在TLS握手过程中,把自己的证书发给客户端,证明自己身份是可信的。证书的两个优化方向:

  • 证书传输
  • 证书验证
证书传输优化

减小证书的大小,可以节约带宽,减少客户端的运算量。对于服务器的证书应该使用椭圆曲线证书(ECDAS),而不是RSA证书,因为在相同安全强度下,ECC密钥长度比RSA短的多。

证书验证优化

客户端在验证证书时,从证书链逐级验证,验证的过程不仅需要用CA公钥解密证书以及用签名算法验证证书的完整性,而且为了知道证书是否被CA吊销,客户端有时还会再去访问CA,下载CRL或者OCSP数据,确认证书的有效性。

CRL

== CRL(Certificate Revocation List,证书吊销列表)==,这个列表由CA定期更新,列表内容都是被撤销信任的证书序号,如果服务器的证书在此列表,就认为证书已经失效,不在的则认为证书是有效的。
在这里插入图片描述
CRL存在两个问题:

  • 由于CRL列表是由CA维护的,定期更新,如果有一个证书刚被吊销,客户端再更新CRL之前还是会信任这个证书,实时性较差
  • 随着吊销证书的增多,列表会越来越大,下载的速度就会越慢,下载完客户端还得遍历这么大的列表,导致客户端在校验证书时延时很大,拖慢HTTPS连接。
OCSP

现在基本都是使用OCSP(Online Certificate Status Protocol,在线证书状态协议)来查询证书的有效性,向CA发送查询请求,让CA返回证书的有效状态
不必像CRL方式客户端需要下载大大的列表,还要从列表查询,因为可以实时查询每一张证书的有效性,解决CRL实时性问题。
OCSP需要像CA查询,因为也要发生网络请求,而且还得看CA服务器的脸色,如果网络状态不佳或CA服务器繁忙,也会导致客户端在校验证书这一环节延时变大。

OCSP Stapling

为解决网络开销问题,出现OCSP Stapling,原理:服务器向CA周期性地查询证书状态,获得一个带有时间戳和签名的响应结果并缓存它。
当有客户端发起连接请求时,服务器就会把这个响应结果在TLS握手过程中发给客户端。由于签名的存在,服务器无法篡改,因此客户端就能得知证书是否被吊销掉,客户端不需要再去查询。

会话复用

TLS握手的目的就是为了协商出会话密钥(对称加密密钥),如果将首次TLS握手协商的对称加密密钥缓存起来,待下次需要建立HTTPS连接时,直接复用这个密钥,就减少了TLS握手的性能损耗。
会话复用分为Session ID和Session Ticket.

Session ID

工作原理:客户端和服务器首次TLS连接后,双方会在内存缓存会话密钥,并于唯一的Session ID来标识,Session ID和会话密钥相当于key-value的关系。
当客户端再次连接时,hello消息会带上Session ID,服务器收到后就会从内存找,如果找到就直接用该会话密钥恢复会话状态,跳过其他的过程,只用一个消息往返就可以建立安全通信。为了安全性,内存中的会话密钥会定期失效。
两个缺点:

  • 服务器必须保持每一个客户端的会话密钥,随着客户端的增多,服务器的内存压力会增大
  • 现在网站服务一般是由多台服务器通过负载均衡提供服务的,客户端再次连接不一定会命中上次访问过的服务器,于是还要走完整的TLS握手过程。
Session Ticket

为解决Session ID的问题,出现Session Ticket,服务器不再缓存每个客户端的会话密钥而是把缓存的工作交给客户端,类似HTTP的Cookie
客户端与服务端首次建立连接时,服务器会加密会话密钥作为Ticket给客户端,交给客户端缓存该Ticket
客户端再次连接服务器时,客户端会发送Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,若无问题,就可以恢复会话,开始加密通信。
对于集群服务器,要确保每台服务器加密会话密钥的密钥是一致的,这样客户端携带Ticket访问任意一台服务器时,都能恢复会话。
Session ID和Session Ticket都不具备前向安全性,因为一旦加密会话密钥的密钥被破解或者服务器泄漏会话密钥,前面劫持的通信密文都会被破解,同时应对重放攻击也很困难。
重放攻击原理
在这里插入图片描述
假设A想向B证明自己的身份,B要求A的密码作为身份证明,A应尽权力提供(可能是在经过如哈希函数的转换之后),于此同时E窃听了对话并保留了密码(如哈希)。
交换结束后,E(冒充A)连接到B。当被要求提供身份证明时,E发从B接受的最后一个会话中读取的A的密码(或哈希),从而授予E访问权限。
重放攻击坏处:如果中间人截获某个客户端的Session ID或Session Ticket以及POST报文,而一般POST请求会改变数据库的数据,中间人就可以利用此截获的报文,不断向服务器发送报文,这样就会导致数据库的数据被中间人改变了,而客户端不知情。
避免重放攻击的方式就是需要对会话密钥设定一个合理的过期时间,以及只针对安全的HTTP请求如GET\HEAD使用会话重用

Pre-shared Key

Session ID和Session Ticket方式需要1RTT才能恢复会话。
重连的TLS1.3只需0RTT。重连时,客户端会把Ticket和HTTP请求一同发送给服务端,这种方式叫Pre-shared Key。
Pre-shared Key也有重放攻击危险。

总结

对于硬件优化,因为HTTPS属于计算密集型,应该选择计算力更强的CPU,而且最好选择支持AES-NI特性的CPU,这个特性可以在硬件级别优化AES对称加密算法,加快应用数据的加解密。
对于软件优化的方向,如果可以,把软件升级成较新的版本,比如将 Linux 内核 2.X 升级成 4.X,将 openssl 1.0.1 升级到 1.1.1,因为新版本的软件不仅会提供新的特性,而且还会修复老版本的问题。
对于协议优化的方向:

  • 密钥交换算法应该选择 ECDHE 算法,而不用 RSA 算法,因为 ECDHE 算法具备前向安全性,而且客户端可以在第三次握手之后,就发送加密应用数据,节省了 1 RTT。
  • 将 TLS1.2 升级 TLS1.3,因为 TLS1.3 的握手过程只需要 1 RTT,而且安全性更强。

对于证书优化的方向:

  • 服务器应该选用 ECDSA 证书,而非 RSA 证书,因为在相同安全级别下,ECC 的密钥长度比 RSA 短很多,这样可以提高证书传输的效率;
  • 服务器应该开启 OCSP Stapling 功能,由服务器预先获得 OCSP 的响应,并把响应结果缓存起来,这样 TLS 握手的时候就不用再访问 CA 服务器,减少了网络通信的开销,提高了证书验证的效率;
    对于重连 HTTPS 时,我们可以使用一些技术让客户端和服务端使用上一次 HTTPS 连接使用的会话密钥,直接恢复会话,而不用再重新走完整的 TLS 握手过程。
    常见的会话重用技术有 Session ID 和 Session Ticket,用了会话重用技术,当再次重连 HTTPS 时,只需要 1 RTT 就可以恢复会话。对于 TLS1.3 使用 Pre-shared Key 会话重用技术,只需要 0 RTT 就可以恢复会话。
    这些会话重用技术虽然好用,但是存在一定的安全风险,它们不仅不具备前向安全,而且有重放攻击的风险,所以应当对会话密钥设定一个合理的过期时间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值