Https的通信过程

43 阅读4分钟

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 连接。

  • 目的:确认客户端和服务端的“发送”与“接收”能力都正常。
  • 流程
    1. SYN (Client -> Server): “喂,听得到吗?” (客户端请求连接)
    2. SYN + ACK (Server -> Client): “听到了,你能听到我吗?” (服务端确认并回请)
    3. ACK (Client -> Server): “听到了,连接建立。” (客户端确认)

3. TLS 握手过程 (安全协商)

TCP 连接建立后,进行 TLS 握手。目的是身份验证协商会话密钥

核心流程 (以 RSA 为例)

  1. Client Hello
    • 客户端发送:支持的协议版本、加密套件列表、随机数 A (Client Random)
  2. Server Hello
    • 服务端返回:确认的版本、选定的加密套件、随机数 B (Server Random)
    • 关键动作:下发 服务器证书 (Certificate)(包含服务器公钥)。
  3. Certificate Verification (证书校验)
    • 客户端验证证书合法性(详见第 4 节)。
    • 如果失败,断开连接并报警。
  4. Key Exchange (密钥交换)
    • 客户端生成 随机数 C (Pre-Master Secret)
    • 客户端用服务器公钥加密随机数 C,发送给服务器。
    • 服务端用私钥解密,拿到随机数 C。
  5. Session Key Generation (生成会话密钥)
    • 双方同时使用 Random A + Random B + Pre-Master Secret
    • 通过 PRF (伪随机函数) 算法计算出最终的 对称密钥 (Session Key)
  6. Finished
    • 双方用 Session Key 加密一段测试消息,互相验证能否解密成功。

后续交互:握手结束,HTTP 请求/响应内容全部使用 Session Key 进行对称加密传输。


4. 证书校验详解 (核心难点)

这是浏览器验证服务端“是不是骗子”的关键步骤。

4.1 校验逻辑流

浏览器拿到证书后,执行以下验证:

  1. 信任链 (Chain of Trust)
    • 查看证书的颁发者 (Issuer)。
    • 递归向上查找,直到找到操作系统内置的 根证书 (Root CA)
  2. 有效期 (Validity)
    • 检查 Current Time 是否在 notBeforenotAfter 之间。
  3. 吊销状态 (Revocation)
    • 通过 OCSP 或 CRL 检查证书是否被 CA 撤回。
  4. 数字签名验证 (Digital Signature Verification)
    • 这是确保证书未被篡改的核心技术手段。

4.2 数字签名验证的底层原理

验证公式:Verify(Data, Signature, Issuer_PublicKey)

具体步骤:

  1. 计算本地哈希 (Hashing)
    • 浏览器提取证书正文 (TBSCertificate)。
    • 使用指定算法 (如 SHA-256) 计算摘要:Hash_Local = SHA256(Content)
  2. 解密签名 (Decryption)
    • 浏览器提取证书底部的签名 (SignatureValue)。
    • 使用颁发者(CA)的公钥对签名进行数学解密运算(RSA 逆运算)。
    • 得到解密后的数据包:Decrypted_Data
  3. 解析与去填充 (Unpadding & Parsing)
    • Decrypted_Data 包含填充位 (Padding) 和 ASN.1 结构。
    • 解析该结构,提取出原始的哈希值:Hash_From_Signature
  4. 比对 (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

  1. 安全性:防止开发者处理 Padding (填充) 时出错,导致安全漏洞 (如 Bleichenbacher 攻击)。
  2. 兼容性:部分现代算法 (如 ECDSA 椭圆曲线) 不支持“公钥解密”这种数学操作,只能进行点校验。库通过 verify 统一了接口。
  3. 复杂性封装:将 ASN.1 解析、大数运算、哈希计算等复杂底层逻辑封装在黑盒里。

C. 为什么要用三个随机数?

  • Client Random + Server Random:明文传输。防止重放攻击 (Replay Attack),保证每次连接的 Session Key 都是独一无二的。
  • Pre-Master Secret:密文传输。保证只有持有私钥的服务器能拿到,是安全的核心。

6. 学习总结

  1. HTTP 是应用层,无状态,明文。
  2. HTTPS 在 HTTP 下面加了一层 TLS。
  3. 证书校验 是利用 非对称加密 (公钥解密签名) 来验证身份。
  4. 数据传输 是利用 对称加密 (协商出的 Session Key) 来提升速度。