通过 Wireshark 抓包理解 HTTPS 的 SSL/TLS 握手
SSL/TLS 的基本思想是
公钥加密, 私钥解密
(非对称加密). 客户端请求时, 服务端先将自己的公钥告诉它, 然后客户端使用公钥对内容加密, 服务端收到之后使用私钥解密.
但是有几个问题:
- 如何保证服务端的公钥不会被篡改. 因为如果请求服务端公钥的过程被拦截, 拦截者返回了一个不正确的公钥, 就会造成问题
- 我们必须具有服务器的公钥。但是, 我们无法存储地球上所有服务器的公钥, 该数据非常庞大, 并且如何保证公钥的修改同步问题
- 公钥加密, 私钥解密(非对称加密)的方式比较耗时, 如果每次数据交换都进行会增大整个请求的耗时
为了解决上面的问题, 引入了 数字证书
和 SSL/TLS 握手
:
- 数字证书: 将公钥放在数字证书中, 只要证书通过客户端验证, 那公钥就是可信的; 数字证书每次由服务端在请求前发送给客户端, 解决了公钥同步问题
- SSL/TLS 握手: 在每一次对话之前, 服务端和客户端通过握手生成一个密钥, 之后的数据都通过这个密钥使用对称加密方式加密, 就避免了每次使用非对称加密的耗时问题
如何验证证书有效
服务端的公钥放在数字证书中, 那客户端是如何验证这个证书的是不是正确的呢?
解决方案是证书颁发机构, 或简称为 CA (根证书机构)。当我们安装操作系统或浏览器时, 可能会附带一系列受信任的 CA。在这些 CA 列表中, 还存储了 CA 的公钥。
- Mac OS: 可以在钥匙串中查看系统信任的证书
- Android:
/system/etc/security/cacerts
文件夹中存有系统信任的证书
比如, 当 Google.com 的服务器向我们发送其证书时, 它还会提到该证书是由 GeoTrust 签名的。如果我们信任 GeoTrust, 则可以使用 GeoTrust 的公钥验证 GeoTrust 是否确实签署了 Google.com 服务器发送给我们的证书。(CRL 或 OCSP)
如果我们要自己签署证书, 我们需要知道私钥, 但私钥只有 GeoTrust 知道。因此攻击者就无法自己签署证书并假装自己是 Google.com。而且证书被修改后, 即使只有一位, 签名也将不正确, 客户端将拒绝它。
OCSP 在线证书状态协议
- Alice 与 Bob 使用 Carol 颁发的数字证书。该场景中 Carol 是证书颁发机构(CA);
- Alice 向Bob 发送其由 Carol 颁发的数字证书,并发出请求创建连接的申请;
- Bob 担心 Alice 的私钥已经泄露,因此向 Carol 发送“OCSP请求”消息并包含 Alice 的数字证书序列号;
- Carol 的OCSP 响应端从 Bob 发送的消息中获取数字证书的序列号,并在 CA 数据库中查找该数字证书的状态;
- Carol 向 Bob 发送由其私钥加密的消息“OCSP响应”,并包含证书状态正常的信息;
- 由于 Bob 事先已经安装了 Carol 的数字证书,因此 Bob 使用 Carol 的公钥解密消息并获取到 Alice 的数字证书状态信息;
- Bob 验证通过后, Bob 决定与 Alice进行通信。
握手过程
高亮的部分就是 TLS 握手的过程
Client Hello | Server Hello | Server certificates | Server Key exchange | Client Key exchange | Server final Respnse |
---|---|---|---|---|---|
Initial Client Message to Server
Client Hello
Client Hello 发送的消息:
属性 | 值 | 描述 |
---|---|---|
Version | TLS 1.0 | 客户端使用的 TLS 版本, Version 2 对应 SSL 2.0, version 3 对应 SSL 3.0,version 3.1 对应 TLS |
Random | … | 随机值是一个4字节的数字,由客户端的日期和时间加上一个 28 字节随机生成的数字组成,该数字最终将与服务器随机值一起使用,以生成一个 master screct ,从 master screct 中可以导出加密密钥 |
Session ID | … | 如果客户端有上一次会话的 session id 的话, 客户端可以携带上, 用它来恢复之前的会话. 因为创建新会话需要占用大量处理器资源来做公钥操作,可以通过恢复具有已建立会话密钥的现有会话来避免这种操作 |
Cipher Suites | 客户端支持的加密算法 | |
Compression Methods | 客户端支持的压缩算法 | |
application layer protocol negotiation | - | ALPN 协议 |
Server Response to Client
Server Hello
Server Hello 发送的消息:
属性 | 值 | 描述 |
---|---|---|
Version | TLS 1.0 | 服务端将选择服务端和客户端支持的最高版本 |
Random | … | 服务端产生的随机值, 产生方法和客户端一样 |
Session ID | … | 服务端为这次会话分配的 id, 有 3 种情况: 1. New Session ID: 如果客户端没有在 Client Hello 消息中携带 Session ID 的话,会生成一个新的; 即使 Client Hello 消息携带了 SessionID, 也有可能服务端已经不能恢复上一次会话了, 这种情况也会生成一个新的 Session ID 2. Resumed Session ID: Client Hello 携带了 Session ID 且服务器会恢复它对应的会话, 服务器就会返回和 Client Hello 携带上来一样的 Session ID 3. Null: 一个新会话,但是服务器不愿意在以后恢复它,因此不会返回任何ID |
Cipher Suite | 服务端从客户端支持的加密算法中选择使用的一个 | |
Compression Methods | 服务端的压缩算法 | |
application layer protocol negotiation | ALPN 协议 |
Server certificates
服务端发送自己的证书: 这里发送了两个证书,一个是网站自己的证书,另一个是网站证书申请使用的二级证书。因为网站的证书不是直接从根证书机构签发的, 所以这里会发送中级颁发机构的证书.
客户端先通过本地的根证书验证中级颁发机构的证书,然后再使用中级颁发结构的证书验证网站的证书。客户端验证证书通过后,会从网站证书中提取公钥.
- blog.jiyang.site: 网站证书
- Let’s Encrypt Authority X3: 中级颁发机构证书
Server Key Exchange
这里服务端在一次通信里做了 2 件事:
- Server Key Exchange
- Server Hello Done
Server Key Exchange: 是一个可选步骤,服务器创建一个临时密钥并将其发送给客户端。客户端可以使用此密钥在此过程的后面加密 Client Key Exchange 消息。仅当公共密钥算法未提供加密客户端密钥交换消息所需的密钥材料时(例如,服务器的证书不包含公共密钥时),才需要执行此步骤
Server Hello Done
此消息表明服务器握手已完成,正在等待客户端的响应
Client Response to Server
Client Key Exchange
这里客户端在一次通信里做了 3 件事:
- Client Key Exchange
客户端使用两个随机值计算出premaster secret
后, 发送 Client Key Exchange message. 在将 premaster secret
传输到服务器之前, 已使用服务器证书中的公钥对其进行了加密. 双方将在本地计算 master secret
并从中获取会话密钥.
如果服务器可以解密此数据并完成协议, 则可以向客户端保证服务器具有正确的私钥. 这一步对于证明服务器的真实性至关重要. 只有具有与证书中的公钥匹配的私钥的服务器才能解密此数据并继续协议下面的步骤.
此消息还将包括协议版本. 服务器将验证它是否与客户端问候消息中发送的原始值匹配. 此措施可防止回滚攻击. 回滚攻击通过操纵消息来工作, 以使服务器和客户端使用安全性较低的协议的较早版本.
- Change Cipher Spec
该消息通知服务器, 将使用刚刚协商的密钥和算法对Client Finished message之后的所有消息进行加密.
- Encrypted Handshake Message
这个报文的目的就是告诉对端自己在整个握手过程中收到了什么数据, 发送了什么数据. 来保证中间没人篡改报文. 其次, 这个报文作用就是确认秘钥的正确性. 因为 Encrypted handshake message
是使用对称秘钥进行加密的第一个报文, 如果这个报文加解密校验成功, 那么就说明对称秘钥是正确的.
Server Final Response
接着服务端又在一次通信里做了 2 件事:
- Change Cipher Spec
此消息通知客户端服务器将开始使用刚刚协商的密钥来加密消息。
- Encrypted Handshake Message
和 Client 上面的 Encrypted Handshake Message
目的一样