一、WireShark
这篇文章是对上一篇文章的补充,主要是使用 WireShark 来进行抓包分析,以更加直观的方式,帮助大家理解 HTTPS 的整个握手过程。
1.1 下载安装
Wireshark 是一个网络抓包分析软件,下载地址为:https://www.wireshark.org/index.html#download ,下载后直接安装即可。启动后,进入主页面,需要先选择对应的抓包网络:
这里我使用的是无线网络,因此选择 WLAN ,双击后即可进入抓包页面。下面我们以 CSDN 的首页 https://www.csdn.net
为例,我们首先通过 ping 命令获取其 IP 地址:
可以看到,其 IP 地址为 47.95.164.112
。为了避免浏览器上其他网站的干扰,我们先通过该 IP 地址进行过滤:
输入过滤条件 ip.addr == 47.95.164.112
后,敲击回车键即可。可以看到 TCP 和 TLS 的握手消息都已经被过滤出来。
1.2 握手流程回顾
这里首先以图片的方式回顾整个 HTTPS 的握手过程:
然后我们再逐步通过 WireShark 进行分析:
二、TCP 握手过程
首先 TLS/SSL 协议是基于 TCP/IP 协议的,因此需要先等待 TCP 三次握手完成:
从上图被被捕获的记录中,可以很直观的看出整个握手过程与下图是完全匹配的:
该过程比较简单,这里就不再进行赘述了。
三、TLS/SSL 握手过程
整个 TLS/ SSL 的握手过程如下:
3.1 Client Hello
TCP 握手完成后,客户端首先发起一个 Client Hello
请求,里面包含客户端版本号、所有支持的密码套件、以及一个随机数 Client Random
:
3.2 Server Hello
服务器收到该请求后,会返回一个 Server Hello
消息,里面包含选中的用于本次通信的密码套件,以及一个随机数 Server Random
;
3.3 Server Hello 的详细过程
接着服务器会在一次返回里面返回多组消息:
这里分别对其进行解释:
1. Certificate
这里面包含的是证书信息:
这里我将里面的部分内容复制了出来:
Certificate: 308206873082056fa00302010202100b038a343b5b17ae92… (id-at-commonName=*.csdn.net,id-at-organizationalUnitName=IT,id-at-organizationName=北京创新乐知信息技术有限公司,id-at-localityName=北京市,id-at-countryName=CN
可以看到,这就是在浏览器中使用的证书的:
2. Certificate Status
这一步主要是依据在线证书状态协议(OCSP,Online Certificate Status Protocol)对当前证书状态进行查询:
3. Server Key Exchange
这里面包含了进行 ECDHE 算法所需的各种参数 Server Params
:
4. Server Hello Done
这个就是用于告知客户端服务器的整个 Hello 过程已经结束,并不包含任何内容:
3.4 Client Key Exchange
之后,客户端按照密码套件的要求,也生成一个 Client Params
,并通过 Client Key Exchange
消息发送给服务器;
Client Key Exchange
具体内容如下:
3.5 计算预主密钥和主密钥
- 经过以上步骤的交换,服务器和客户端都有了
Client Params
和Server Params
,它们分别根据这两个参数进行计算,ECDHE 算法能够保证客户端和服务器算出来的值是一样的,这个算出来的值就是预主密钥Pre-Master
; - 最后再利用预主秘钥,客户端随机数,服务器随机数共同算出真正的主密钥
Master_Secret
,算法如下:
这里的 PRF 是一个伪随机函数,用于增强 master_secret 的随机性。主密钥master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
Master_Secret
的长度固定为 48 个字节,从中可以推导出以下四个密钥:* client_write_MAC_key- server_write_MAC_key
- client_write_key
- server_write_key
client_write_MAC_key
和server_write_MAC_key
主要用于身份验证和完整性校验,而client_write_key
和server_write_key
则是对称加密中真正使用的会话密钥: - 客户端使用
client_write_key
加密,服务器对称地使用client_write_key
解密; - 服务器使用
server_write_key
加密,客户端对称地使用server_write_key
解密。
3.6 Change Cipher Spec
有了会话密钥后,客户端会发送一个 Change Cipher Spec
请求,告知服务器将加密方式由非对称加密转换为对称加密;
3.7 Encrypted Handshake Message
紧接着,为了验证对称加密,客户端会将所有的握手消息(Handshake Message)进行加密,通过一个 Encrypted Handshake Message
请求发送给服务器;
3.8 New Session Ticket
- 服务器解密并进行验证,如果验证通过,则也返回给客户端
Change Cipher Spec
和Encrypted Handshake Message
消息,代表双方共同达成协议,之后的通信都采用对称加密的方式。 - 除此之外,服务器还会返回一个
New Session Ticket
消息。New Session Ticket
是一种优化连接的方式:服务器将会话信息加密后以 Ticket(票据)的方式发送给客户端 ,服务器本身并不存储会话信息。客户端接收到 Ticket 后,将其储到内存中,如果想恢复会话,则下次连接的时候将票据发送给服务器端;服务器端进行解密,如果确认无误则表示可以进行会话恢复,这样就简化了以上复杂的握手过程。
至此,握手过程全部完成。