HTTPS 握手过程
通过 Wireshark 抓包分析 HTTPS 完整握手流程
问题
HTTPS 的握手过程是怎样的?
解答
HTTPS 在 OSI 七层协议中属于应用层,基于 TCP 协议。因此 HTTPS 握手必须先完成 TCP 三次握手,建立 TCP 连接后才进入对称密钥协商过程,协商完成后开始正常收发数据。
抓包准备
使用 Wireshark 抓包工具,执行以下命令:
curl https://www.baidu.com
为什么选择 Wireshark?
Fiddler 和 Charles 主要抓取应用层协议(HTTP/HTTPS)的数据,都是连接建立后的数据。而 Wireshark 直接读取网卡数据,可以抓取所有协议的数据包,包括握手过程。
为什么使用 curl?
curl 只发送一个请求,如果用浏览器打开百度,页面中的各种资源也会发送请求,产生大量不必要的数据包。
握手流程
第一步:TCP 三次握手
建立 TCP 连接(此处省略 TCP 握手细节)。
第二步:客户端发送 Client Hello
客户端发送 client_hello,包含:
- TLS 版本信息
- 随机数
random_C(用于后续密钥协商) - 加密套件候选列表
- 压缩算法候选列表
- 扩展字段
第三步:服务端发送 Server Hello
服务端收到 client_hello 后,返回协商结果:
- 选择的 TLS 协议版本
- 选择的加密套件
- 选择的压缩算法
- 随机数
random_S
第四步:服务端发送证书
服务端发送自己的证书。由于证书报文长度较大(如 3761 字节),TCP 层会进行分段,分多个报文发送。
第五步:服务端发送 Server Key Exchange
服务端发送密钥交换参数。
第六步:服务端发送 Server Hello Done
通知客户端 server_hello 信息发送结束。
第七步:客户端发送密钥信息
客户端发送三个消息:
client_key_exchange:验证证书合法性后,发送自己的公钥参数,此时客户端已计算出密钥change_cipher_spec:通知服务器后续通信采用协商的密钥和加密算法encrypted_handshake_message:测试密钥的有效性和一致性
第八步:服务端发送 New Session Ticket
服务器给客户端一个会话票据,在超时时间内双方使用协商的密钥通信。
第九步:服务端发送 Change Cipher Spec
服务端解密客户端参数,计算出协商密钥,通过 encrypted_handshake_message 验证有效性。验证通过后发送此报文,告知客户端可以使用协商密钥通信。
第十步:服务端发送 Encrypted Handshake Message
服务端测试密钥有效性,验证客户端能正常解密,服务端能正常加密。
第十一步:开始传输数据
密钥协商完成,使用对称加密传输数据(数据可能分段发送)。
第十二步:TCP 四次挥手
数据传输完成后,通过 TCP 四次挥手关闭连接。期间可能发送加密警告消息,表示加密通信需要中断。
关键点
- HTTPS 握手前必须先完成 TCP 三次握手
- 客户端和服务端各生成一个随机数(random_C 和 random_S),用于协商对称密钥
- 服务端发送证书供客户端验证身份
- 双方通过
encrypted_handshake_message相互验证密钥的有效性 - 握手完成后使用协商的对称密钥加密传输数据
目录