HTTP、HTTPS 与 TLS 协议详解笔记
1. 协议分层架构
首先明确网络协议的层级关系,这是理解一切的基础。HTTPS 并非独立协议,而是 HTTP over TLS。
graph TD
A[Application Layer: HTTP] -->|Data| B[Security Layer: TLS/SSL]
B -->|Encrypted Data| C[Transport Layer: TCP]
C -->|Packets| D[Network Layer: IP]
- TCP: 负责建立可靠连接(修路)。
- TLS: 负责加密和验证(安检 & 隧道)。
- HTTP: 负责传输应用数据(跑车)。
2. TCP 三次握手 (建立连接)
HTTP 请求发送前,必须先建立 TCP 连接。
- 目的:确认客户端和服务端的“发送”与“接收”能力都正常。
- 流程:
- SYN (Client -> Server): “喂,听得到吗?” (客户端请求连接)
- SYN + ACK (Server -> Client): “听到了,你能听到我吗?” (服务端确认并回请)
- ACK (Client -> Server): “听到了,连接建立。” (客户端确认)
3. TLS 握手过程 (安全协商)
TCP 连接建立后,进行 TLS 握手。目的是身份验证和协商会话密钥。
核心流程 (以 RSA 为例)
- Client Hello
- 客户端发送:支持的协议版本、加密套件列表、随机数 A (Client Random)。
- Server Hello
- 服务端返回:确认的版本、选定的加密套件、随机数 B (Server Random)。
- 关键动作:下发 服务器证书 (Certificate)(包含服务器公钥)。
- Certificate Verification (证书校验)
- 客户端验证证书合法性(详见第 4 节)。
- 如果失败,断开连接并报警。
- Key Exchange (密钥交换)
- 客户端生成 随机数 C (Pre-Master Secret)。
- 客户端用服务器公钥加密随机数 C,发送给服务器。
- 服务端用私钥解密,拿到随机数 C。
- Session Key Generation (生成会话密钥)
- 双方同时使用
Random A + Random B + Pre-Master Secret。 - 通过 PRF (伪随机函数) 算法计算出最终的 对称密钥 (Session Key)。
- 双方同时使用
- Finished
- 双方用 Session Key 加密一段测试消息,互相验证能否解密成功。
后续交互:握手结束,HTTP 请求/响应内容全部使用 Session Key 进行对称加密传输。
4. 证书校验详解 (核心难点)
这是浏览器验证服务端“是不是骗子”的关键步骤。
4.1 校验逻辑流
浏览器拿到证书后,执行以下验证:
- 信任链 (Chain of Trust):
- 查看证书的颁发者 (Issuer)。
- 递归向上查找,直到找到操作系统内置的 根证书 (Root CA)。
- 有效期 (Validity):
- 检查
Current Time是否在notBefore和notAfter之间。
- 检查
- 吊销状态 (Revocation):
- 通过 OCSP 或 CRL 检查证书是否被 CA 撤回。
- 数字签名验证 (Digital Signature Verification):
- 这是确保证书未被篡改的核心技术手段。
4.2 数字签名验证的底层原理
验证公式:Verify(Data, Signature, Issuer_PublicKey)
具体步骤:
- 计算本地哈希 (Hashing)
- 浏览器提取证书正文 (
TBSCertificate)。 - 使用指定算法 (如 SHA-256) 计算摘要:
Hash_Local = SHA256(Content)。
- 浏览器提取证书正文 (
- 解密签名 (Decryption)
- 浏览器提取证书底部的签名 (
SignatureValue)。 - 使用颁发者(CA)的公钥对签名进行数学解密运算(RSA 逆运算)。
- 得到解密后的数据包:
Decrypted_Data。
- 浏览器提取证书底部的签名 (
- 解析与去填充 (Unpadding & Parsing)
Decrypted_Data包含填充位 (Padding) 和 ASN.1 结构。- 解析该结构,提取出原始的哈希值:
Hash_From_Signature。
- 比对 (Comparison)
- 判断:
Hash_Local === Hash_From_Signature? - 相等:证明内容未被篡改,且确实由持有私钥的 CA 签发。
- 不等:证书无效。
- 判断:
5. 关键概念辨析 (FAQ)
A. 加密 vs 签名 (非对称加密的双重用法)
虽然都是用公钥/私钥,但方向和目的完全不同:
| 场景 | 方向 | 目的 |
|---|---|---|
| 加密 (Encryption) | 公钥加密 -> 私钥解密 | 保密。只有私钥持有者能看到内容。 |
| 签名 (Signing) | 私钥加密 -> 公钥解密 | 认证/防篡改。证明是私钥持有者发的,且内容完整。 |
B. 为什么 JS 库只提供 verify() 而不是 decrypt()?
在 Node.js crypto 或浏览器 Web Crypto API 中,你只能调用 verify(pubKey, data, sig) 返回 true/false。
- 安全性:防止开发者处理 Padding (填充) 时出错,导致安全漏洞 (如 Bleichenbacher 攻击)。
- 兼容性:部分现代算法 (如 ECDSA 椭圆曲线) 不支持“公钥解密”这种数学操作,只能进行点校验。库通过
verify统一了接口。 - 复杂性封装:将 ASN.1 解析、大数运算、哈希计算等复杂底层逻辑封装在黑盒里。
C. 为什么要用三个随机数?
- Client Random + Server Random:明文传输。防止重放攻击 (Replay Attack),保证每次连接的 Session Key 都是独一无二的。
- Pre-Master Secret:密文传输。保证只有持有私钥的服务器能拿到,是安全的核心。
6. 学习总结
- HTTP 是应用层,无状态,明文。
- HTTPS 在 HTTP 下面加了一层 TLS。
- 证书校验 是利用 非对称加密 (公钥解密签名) 来验证身份。
- 数据传输 是利用 对称加密 (协商出的 Session Key) 来提升速度。