HTTP

:::info HTTP是基于TCP/IP协议上构建的无状态协议,是一种应用层协议,明文传输 ::: 无状态协议是指每次传输过程中不会记录传输的状态,每次传输完数据后会直接断开,链接无法复用
明文指没有加密的报文,HTTP协议的请求在Charles上看是可以直接看到相关传输数据的

HTTP协议存在很严重的问题:不够安全,数据无法保密、数据完整性无法验证、服务端身份不置信
每次传输过程中,没有校验服务端是否可信,容易被劫持(中间人攻击),明文传输会导致数据泄露、篡改的风险

TCP三次握手

TCP是传输层协议,主要用来传输数据,TCP每次链接和断开时需要进行三次握手与四次挥手
在wireShark中相对序列号Seq和确认号Ack都是以0开头,绝对序列号初始值是随机的32位二进制数,相对序列号比较容易跟踪
SYN表示创建一个TCP连接,ACK表示确认接收到数据,FIN表示结束一个TCP链接
Seq表示当前端发送的数据位数,Ack表示当前端接收到的数据位数,SYN和FIN是标志位也占据一位,所以在进行TCP三次握手时,客户端发送SYN,序列号Seq = 0,服务端响应时序列号依旧是Seq = 0,表示当前时刻服务端还没发送过数据,Ack=1表示当前已接收了客户端的一位数据
从包1开始,TCP连接已经完成,开始用于传输数据,客户端发送长度为517的数据给服务端,此时客户端发送和接收了一个标志位,所以seq = 1,Ack = 1
包2是服务端对客户端响应,此时服务端只发送了一个标志位,所以Seq = 1,接收了一个标志位+517位长度的数据,所以Ack = 518
以此类推
image.png
tcp三次握手的原因:TCP为全双工通信,为了实现可靠传输,服务端和客户端都有确认双方的连接时成功,如果只有2次握手,服务端响应了客户端,客户端确认已经连接成功可以发送数据了,但服务端不确定客户端是否接收到数据,无法保证数据传输是成功的,如果有4次握手,在第3次的时候服务端和客户端分别已经确定双方的连接时成功的,多的一次握手会降低传输效率
tcp四次挥手:TCP的数据传输时是相互的,断开TCP连接时不是同时进行的,只有两方主动断开时,TCP连接才会完全断开,客户端给服务端发送FIN标志,表明需要结束连接,服务端响应之后,客户端不能在给服务端发送数据了,但是服务端还可以持续的给客户端发送数据,直到服务端要结束连接

HTTP2

由于浏览器对于同一个域名的请求并发数(TCP链接)是有控制的,一般为6-8个,当请求较多时,超过的请求会挂起等待前面的请求结束
HTTP1.1增加了keep-alive的功能,即一段时间内可以复用TCP链接,但是请求依旧是串行发送的,即需要等服务端响应后客户端才发送第二个请求,TCP链接并发数量的控制依旧存在
HTTP1.1也引入了管道机制,即客户端可以并行在一个TCP链接中发送多个请求,但是服务端的响应依旧是按客户端发送请求的顺序来的,前一个请求没有响应就会阻塞后一个请求

HTTP2在HTTP1.1的基础上增加了二进制分帧、多路复用、服务端推送、头部压缩等功能
HTTP2传输方式为二进制数据流传输,对于客户端的请求可以以帧的形式并行发送多个请求数据
多路复用即同一个域名只会建立一个TCP链接,所有的请求和响应都在这个链接里传输,以数据流的形式分帧发送,帧首部有固定的标识可以重新组装

HTTPS

HTTPS是为了解决HTTP协议存在的安全问题,在HTTP与TCP中间增加了TSL(TLS1.0是在SSL3.0的基础上发布的,目前基本上用的是TLS1.2版本)加密层,对数据进行加密传输,对服务器进行身份验证,防止数据劫持
TSL层主要依赖的算法有非对称加密,对称加密,摘要算法(又称散列函数、哈希函数)等,统称为加密套件来确保传输安全
非对称加密算法进行秘钥协商和身份认证,主要的算法有RSA、DH、ECDHE
对称加密算法对数据传输进行加密,比如AES
摘要算法因为对输入具有单向性(不可逆),且输入微小的改变都会引起输出的剧烈变化,用于保证数据的完整性,摘要算法可以将任意长度的数据计算成固定长度的且独一无二的数字摘要,发送原文和数字摘要,接收者将接收到的原文通过同样算法计算出数字摘要,与收到的数字摘要对比即可知道数据是否被篡改过

对称加密与非对称加密

对称加密在加密和解密过程中使用同一个秘钥,如果劫持者劫持了密钥就很容易解密,非对称加密有公钥和私钥一对秘钥,用公钥加密的数据只有私钥可以解密,用私钥加密的数据只有公钥可以解密

非对称加密的公钥和私钥都存于服务端,公钥是服务端发送给客户端的,是公开的,传递公钥的过程可能会被拦截篡改
由于对称加密安全性不高,而非对称加密的加解密时间长会导致传输效率降低,HTTPS使用非对称加密和对称加密的组合方式,非对称加密协商产生对称加密过程中的秘钥,但这种方式仍然存在中间人篡改的风险,即中间人拦截服务端发送的公钥,伪造服务端发送新的公钥给客户端,所以就需要验证服务端的身份,即数字签名

CA认证

服务端通过私钥加密一段能表明自己身份的数据(数字摘要)生成数字签名,和原文一起传递给客户端,客户端通过公钥解密后和原文对比就可以确定服务端的身份,但只要存在传递公钥的过程就可能会被拦截篡改,所以数字签名一般由比较权威的第三方机构(CA)发布,称为数字证书(包含公钥和其他信息,以及这些信息的数字签名)

CA证书颁发过程:服务端登记公钥和相关信息至CA,CA验证后,将服务端公钥、服务的相关信息、CA机构信息以及一些其他信息使用散列函数得到数字摘要,用CA的私钥加密数字摘要后生成数字签名,数字签名与原始信息合在一起就成为数字证书

TLS1.2秘钥协商过程

目前主流应用的是TLS1.2版本,TLS1.3版本在前一个版本上优化了安全性和连接速度,以TLS1.2为例
不同的非对称加密协议有不同的秘钥协商过程

秘钥首次协商流程

RSA与DH是比较常见的非对称加密算法,核心思想是使用三个随机数生成会话秘钥,会话秘钥不只有一个,根据主密钥可以扩展出多个会话秘钥,比如服务端发送用的会话秘钥、客户端发送用的会话秘钥

RSA算法秘钥交换

RSA算法最初通过Client Hello与Server Hello的信息交换,客户端与服务端都分别持有两个随机数,确认服务端身份无误后,客户端拿到公钥
第二步,客户端新生成随机数预主密钥,与前两个随机数经过算法生成主密钥,然后主密钥计算扩展出多个会话秘钥,客户端和服务端分别用自己计算出的会话秘钥解密出握手信息,则表明协商成功,后续都会用会话秘钥加密信息
HTTPS - 图2

ECDHE算法秘钥交换

EC表示椭圆曲线,DH表示D-H算法、E表示临时的秘钥交换
ECDHE算法的过程与RSA相似,不同点在于预主密钥的生成,RSA算法是客户端生成然后发送给服务端,ECDHE是客户端和服务端分别临时生成一对秘钥对,在握手过程中交换D-H参数和各自的公钥,预主秘钥就是通过各自的私钥和D-H参数计算出来的
RSA算法只需要客户端验证CA证书即可确认服务端身份,但ECDHE算法存在临时秘钥对交互数据,所以在服务端发送的Server Key Exchange中需要携带签名(Client Random、Server Random、算法参数、服务端ECDH公钥的数字摘要,并用证书私钥进行加密),用来验证服务端的身份,客户端用证书公钥解密后能对应上就代表身份认证成功

HTTPS - 图3

会话复用与恢复

如果每次HTTPS请求都进行TLS握手,那必定会导致传输效率降低,传输时间变长,所以TLS协议会缓存握手过程来优化传输速度,称为会话恢复
会话恢复目前有两种方式:Session Id与Session Ticket,主要原理就是保持协商出来的主秘钥,会话复用的时候仍然使用主密钥扩展出会话秘钥,这样就不用经历一次完整的秘钥协商过程了

Session Id

Session Id是一个会话标识符,每一个会话都有独一无二的Session Id,对于支持Session Id的服务器,第一次连接时会在Server Hello返回Session Id,并以Session Id为key,主秘钥为value的键值对存在在客户端和服务端,如果服务器不支持Session Id会返回为空
缺点:

  • 服务端需要存储Session Id键值对,当客户端数量数量较多时会占较多内存,
  • 当服务端的机器较多时如果不进行数据同步,则换一台服务机器后需要重新协商,存储就失效了,如果同步数据,同步间的延迟也会存在

假设客户端与服务端之前有过连接,会话恢复具体步骤如下image.png

  • 客户端发送Client Hello,带上Session Id

image.png

  • 服务端接收到Session Id后再内存中查找对应的key和value,如果有,且加密套件也与上一次一致,则会恢复会话,在Server Hello中的Session Id中返回同样的Session Id,并通知客户端更改会话加密方式,将握手信息的数字摘要使用新的会话秘钥(主秘钥重新计算)加密发送给客户端
  • 客户端收到后同样发送Change Cipher Spec和Encrypted Handshake Message,恢复过程结束

    Session Ticket

    Session Ticket是为了解决Session Id缺点设计的更优的会话恢复方案,Session Ticket类似与HTTP Cokkie的存储方式,将会话信息(包含主密钥)数据加密存在客户端,解密的秘钥只有服务端知道,服务端只需要验证客户端传输来的加密数据即可
    第一次连接时客户端会带上空的Session Ticket扩展表明客户端支持该方案,如果服务端也支持,在Server Hello中也会返回空的Session Ticket扩展,然后在后续的过程中发送New Session Ticket信息,将包含主密钥的会话信息加密发送给客户端,如果服务端不支持,则Server Hello中不会带上Session Ticket扩展
    image.png
    假设客户端与服务端之前有过连接,会话恢复具体步骤如下

  • 客户端发送Client Hello,扩展里带上Session Ticket

  • 服务端如果支持Session Ticket,会在Server Hello中带上空的Session Ticket扩展,并重新生成一个新的ticket,在New Session Ticket发送给客户端,然后发送Change Cipher Spec和Encrypted Handshake Message
  • 客户端回复Change Cipher Spec和Encrypted Handshake Message,协商结束

    同时存在Session Id和Session Ticket

    当客户端同时发送Session Id和Session Ticket时,场景比较特殊

    如果 Client 在 Client Hello 中同时发送了 Session ID 和 SessionTicket TLS 扩展,Server 必须用 Client Hello 中相同的 Session ID 进行响应。但是在校验是否可复用时,Sever 不能依赖这个特定的 Session ID,即不能用 Client Hello 中的 Session ID 进行会话恢复。Server 优先使用 SessionTicket 进行会话恢复(SessionTicket 优先级高于 Session ID),如果 Session 校验通过,就继续发送 ChangeCipherSpec 和 Finished 消息。不发送 NewSessionTicket 消息。

  • Client Hello

image.png

  • Server Hello

image.png

会话恢复存储主密钥的原因

在会话恢复过程中存储的信息是主密钥,而不是预主秘钥或会话秘钥
非预主秘钥的原因:

  • 预主密钥在RSA算法中是随机生成的,在ECDHE算法中是算法生成的,而主密钥是由两个随机数与预主密钥计算生成的,更加具有随机性,也就更加安全
  • 预主密钥在不同算法中生成的长度不一致,而主密钥是要求48位长度,比较好统一

非会话秘钥的原因:

  • 如果存储的会话秘钥,那么ticket未过期之前,会有被攻击者截取用于重放攻击的风险,而存储主密钥,每次进行协商的时候会生成新的Client Random、Server Random,会话秘钥也会被重新计算,安全性会高一点

    WireShark抓包TLS握手协商过程

    由于HTTPS是在HTTP和TCP中间添加了TLS,故首先要进行TCP三次握手,使用TCP传输协商过程的相关数据,下面每一个TLS协议记录都是使用TCP传递数据,存在多个TLS记录对应一个TCP包传输
    image.png
    TLS1.2握手过程如下

  • 客户端发送Client Hello,

包含TLS版本、Client Random、加密套件(Cipher Suites)、Session ID、session_ticket,Session ID与session_ticket主要用于会话恢复,首次协商会话秘钥没有用到,如果之前与该服务没有进行过TLS链接,Session ID应该为空
image.png

  • 服务端发送Server Hello

包含TLS版本、Server Random,并确认使用的加密套件,选用ECDHE算法作为秘钥交换算法,RSA用于验证服务端身份,Server Key Exchange发送的签名使用的是RSA算法,经过服务端私钥加密后发送到客户端,客户端那公钥解密验证身份,AES为对称加密算法,128为秘钥长度,SHA256为消息摘要算法,Session Id不存在,则表明服务器不支持Session Id会话恢复,而Session Ticket扩展存在则表明服务器支持Session Ticket会话恢复
image.png

  • 服务端发送Certificate、Server Key Exchange、Server Hello Done

证书为CA证书,包含服务端公钥,Server Key Exchange除了用户身份认证的签名外,还有EC D-H算法参数、服务端临时秘钥对的公钥用于生成预主密钥
image.png

  • 客户端发送Client Key Exchange、ChangeCipher Spec、Encrypted Handshake Message

Client Key Exchange发送客户端ECDH算法,即客户端临时秘钥对的公钥,Change Cipher Spec表示后续数据传输都要是有加密传输,此时客户端已经根据已有信息计算出会话秘钥,并将所有握手信息的数字摘要使用会话秘钥加密传递给服务端
image.png

  • 服务端发送New Session Ticket、Change Cipher Spec、Encrypted Handshake Message

New Session Ticket是用于会话复用的,这里服务端解密成功后,通知客户端使用会话秘钥加密传输,并也将握手信息的数字摘要用会话秘钥加密后发送给客户端,客户端解密成功后协商过程完成
image.png

TLS优化方向

由于TCP链接使用长链接后优化空间有限,则HTTPS链接主要优化在TLS上,TLS1.3在TLS1.2上主要在连接速度与安全性上进行了优化
保障安全性:

  • 删除RSA非对称加密算法的加密套件,默认秘钥交换算法都是椭圆曲线算法

减少TLS握手时间: