TLS 握手过程

HTTP 明文传输,随意使用一个抓包工具都可以截获通信的内容。出于安全性,HTTPS 在 HTTP 与 TCP 层之间加入了 TLS 协议,保证通信数据的隐私与安全。HTTPS 是应用层协议,需要先完成 TCP 建立,再进行 TLS 握手,才能建立通信安全的连接。

不同的密钥交换算法,会使 TLS 的握手过程存在一些区别。不过,由于非对称加密性能比对称加密性能差许多,TLS 握手过程通常先进行非对称加密通信,再协商出一个对称加密密钥。

RSA 握手过程

TLS 证书被部署到服务端时,证书其实就是服务端的公钥,它在 TLS 握手阶段传递给客户端。服务端的私钥一直留在服务端,必须确保私钥不能被第三方窃取。

RSA 密钥协商算法中,客户端会生成随机密钥,并使用服务端的公钥加密后,传回服务端。根据非对称加密算法,公钥加密的信息仅能通过私钥解密。由服务端解密后,双方就得到了相同的密钥。后续的请求全用该随机密钥加密信息。不过实践中的 RSA 握手过程有点差异,小林 coding 的笔记中有详细抓包的过程。

TLS 第 1 次握手

客户端发送 Client Hello 消息,包含 TLS 版本号、随机数 C、支持的密码套件列表等信息。

TLS 第 2 次握手

服务端收到 Client Hello 消息后,会确认 TLS 版本号是否支持,并从支持的密码套件列表里选择一个密码套件,并生成随机数 S。将它们打包成 Server Hello 消息传回客户端。

服务端为了证明自己身份,发送 Server Certificate 给客户端,它包含了数字证书以及公钥。

服务端最后发送 Server Done 消息,告知客户端第 2 次消息传输结束。

TLS 第 3 次握手

客户端根据操作系统内置的根证书,校验服务端的证书是否真实有效,这一步可以防止中间人攻击。

客户端校验成功后,在本地生成一个新的随机数 Pre-Master。随后使用服务端的 RSA 公钥加密该随机数,通过 Client Key Exchange 消息传递给服务端。

至此,客户端与服务端双方都共享了三个随机数,分别是随机数 C,随机数 S,随机数 Pre-Master。双方都可以通过三个随机数,生成相同的会话密钥(Master Secret),用于后续对 HTTP 请求和响应的数据加解密。

客户端生成完会话密钥后,发送 Change Cipher Spec 消息,告知服务端后续消息请加密发送。

最后,客户端发送 Encrypt Handshake Message 消息,将之前所有发送的数据做个摘要,再用会话密钥加密一下,让服务端验证。验证加密通信是否可用、握手信息是否有被篡改。

TLS 第 4 次握手