HTTPS加密工作流程详解
一、 核心问题与解决思路
1.1 HTTP的三大安全问题
问题 1: 窃听
─────────────────────────
客户端 ───[明文数据]───> 服务器
↑
攻击者能看到
问题 2: 篡改
─────────────────────────
客户端 ───[数据]───> 攻击者修改 ───> 服务器
↓
改成假数据
问题 3: 冒充
─────────────────────────
客户端 ───[请求]───> 假服务器
↓
窃取用户信息
1.2 HTTPS 的解决方案
┌─────────────────────────────────────────┐
│ 对称加密 → 解决窃听和篡改 │
│ 非对称加密 → 解决密钥交换问题 │
│ 数字证书 → 解决身份冒充问题 │
└─────────────────────────────────────────┘
二、对称加密的工作流程
2.1 基本原理
对称加密 = 加密和解密用同一把钥匙
┌─────────┐ 密钥K ┌─────────┐ 密钥K ┌─────────┐
│ 明文 │ ─────────> │ 密文 │ ─────────> │ 明文 │
│ Hello │ 加密 │ Kf9sL2 │ 解密 │ Hello │
└─────────┘ └─────────┘ └─────────┘
发送方 传输中 接收方
↑
│ 攻击者即使拦截也无法解密
│ (没有密钥K)
2.2 对称加密的优点
✓ 速度快
- 适合加密大量数据
- 1GB 数据几秒钟就能加密完
✓ 安全性高
- 只要密钥不泄露,几乎无法破解
✓ 计算开销小
- CPU 占用低
- 有硬件加速
2.3 对称加密的问题
❌ 密钥如何安全传递?
场景: Alice 想给 Bob 发送加密消息
Alice Bob
| |
| 步骤1: 我们用密钥"abc123" |
|────────"abc123"──────────>|
| |
↑
│ 问题: 密钥必须通过网络传输
│ 攻击者可以拦截密钥
│ 拦截后就能解密所有通信!
中间人
┌─────┐
│ 👀 │ 看到了密钥 "abc123"
└─────┘ 可以解密后续所有消息
核心矛盾
需要加密通信 → 需要共享密钥 → 如何安全传递密钥?
三、非对称加密的工作流程
3.1 基本原理
非对称加密 = 一对密钥(公钥 + 私钥)
密钥对特性:
├─ 公钥加密的,只能用私钥解密
└─ 私钥加密的,只能用公钥解密
生成密钥对:
Bob生成 ──> 公钥(可以公开) + 私钥(严格保密)
3.2 加密通信流程
场景: Alice 给 Bob 发送秘密消息
准备阶段:
─────────────────────────────────
Bob: 生成密钥对
├─ 公钥: PubKey_Bob (公开发布)
└─ 私钥: PrivKey_Bob (自己保管)
步骤 1: 获取公钥
─────────────────────────────────
Alice Bob
| |
| 请求公钥 |
|───────────────────────────>|
| |
| PubKey_Bob |
|<─────────────────────────── |
| |
说明: 公钥可以公开传输,不怕被窃听
步骤 2: 加密消息
─────────────────────────────────
Alice:
┌──────────┐ 用Bob的公钥 ┌──────────┐
│ 明文 │ ────────────> │ 密文 │
│ "Hello" │ 加密 │ "Kf9sL2" │
└──────────┘ └──────────┘
↓
只有Bob的私钥能解密
步骤 3: 发送密文
─────────────────────────────────
Alice Bob
| |
| 密文 "Kf9sL2" |
|───────────────────────────>|
| |
↑
中间人拦截
┌──────┐
│ 👀 │ 看到了密文
└──────┘ 但没有私钥,无法解密!
(只有公钥没用)
步骤 4: 解密消息
─────────────────────────────────
Bob:
┌──────────┐ 用自己的私钥 ┌──────────┐
│ 密文 │ ────────────> │ 明文 │
│ "Kf9sL2" │ 解密 │ "Hello" │
└──────────┘ └──────────┘
只有 Bob 有私钥 → 只有 Bob 能解密
3.3 非对称加密的优点
✓ 密钥分发简单
- 公钥可以公开传输
- 不担心被窃听
✓ 不需要预先共享密钥
- 任何人都可以用公钥加密
- 只有私钥持有者能解密
3.4 非对称加密的问题
❌ 速度非常慢
- 比对称加密慢 100~1000 倍
- 不适合加密大量数据
示例:
对称加密 1GB 数据: 几秒
非对称加密 1GB 数据: 几小时!
四、HTTPS 的混合加密策略
4.1 核心思想
结合对称加密和非对称加密的优点!
┌──────────────────────────────────────┐
│ 阶段 1: 用非对称加密传递对称密钥 │
│ (只用一次,速度慢也能接受) │
├──────────────────────────────────────┤
│ 阶段 2: 用对称密钥加密所有实际数据 │
│ (速度快,适合大量数据) │
└──────────────────────────────────────┘
4.2 完整工作流程
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
阶段 1: 握手阶段 (非对称加密)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
客户端 服务器
| |
| ① 请求建立连接 |
| - 我支持哪些加密算法 |
| - 客户端随机数A |
|─────────────────────────────────────>|
| |
| | ② 服务器响应
| - 选择加密算法 | - 选定加密算法
| - 服务器随机数B | - 生成随机数
| - 数字证书(含公钥) | - 发送证书
|<─────────────────────────────────────|
| |
| ③ 客户端验证证书 |
| - 检查证书是否可信 |
| - 提取服务器公钥 |
| |
| ④ 生成对称密钥 |
| - 客户端生成随机数C |
| (称为预主密钥) |
| - 用服务器公钥加密随机数C |
| |
| 加密的随机数C |
|─────────────────────────────────────>|
| |
| | ⑤ 服务器解密
| | - 用私钥解密
| | - 得到随机数C
| |
| ⑥ 双方用相同方法计算对称密钥 |
| 密钥 = 函数(随机数A, 随机数B, 随机数C)
| |
| 双方现在有了相同的对称密钥! |
| |
重点:
- 随机数C用非对称加密传输(安全但慢)
- 只传输一次
- 攻击者即使拦截也无法获得随机数C
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
阶段 2: 数据传输阶段 (对称加密)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
客户端 服务器
| |
| HTTP 请求 |
| ──> 用对称密钥加密 ──> [密文1] |
|─────────────────────────────────────>|
| | ──> 用对称密钥解密
| | ──> 处理请求
| |
| | HTTP 响应
| <── 用对称密钥解密 <── [密文2] <── |
|<─────────────────────────────────────|
| |
| 后续所有通信都用对称密钥 |
|<=====================================>|
| 速度快! |
重点:
- 实际数据用对称加密(速度快)
- 双方用相同的对称密钥
- 攻击者没有密钥,无法解密
4.3 为什么需要三个随机数?
随机数来源越多,最终密钥越难越测
客户端随机数A: 客户端生成
服务器随机数B: 服务器生成
预主密钥C: 客户端生成
最终对称密钥 = 复杂函数(A, B, C)
好处:
├─ 即使攻击者控制了客户端,也不知道B和C
├─ 即使攻击者控制了服务器,也不知道C
├─ 必须同时知道A、B、C才能计算出密钥
└─ 每次连接的密钥都不同(因为随机数每次不同)
五、数字证书的作用
5.1 为什么需要证书?
问题: 如何确认公钥真的属于服务器?
中间人攻击示例:
─────────────────────────────────
客户端 攻击者 真实服务器
| | |
| ① 请求公钥 | |
|───────────────────────>| |
| | ② 请求公钥 |
| |──────────────────────>|
| | |
| | ③ 真实公钥 |
| |<──────────────────────|
| | |
| ④ 假公钥 | |
|<───────────────────────| |
| | |
| ⑤ 用假公钥加密密钥 | |
|───────────────────────>| |
| | ⑥ 用假私钥解密 |
| | → 得到密钥! |
| | |
结果: 攻击者冒充服务器,窃取了密钥和所有数据!
5.2 证书的本质
数字证书 = 服务器信息 + 公钥 + CA的签名
┌─────────────────────────────────────┐
│ 证书内容: │
│ ├─ 域名: www.example.com │
│ ├─ 公司: Example Inc │
│ ├─ 有效期: 2024-01-01 到 2025-01-01 │
│ ├─ 公钥: [服务器的公钥] │
│ └─ 证书颁发机构: DigiCert CA │
│ │
│ CA的签名: │
│ └─ [CA用自己私钥签名的数据] │
└─────────────────────────────────────┘
证书的作用:
证明 "这个公钥确实属于 www.example.com"
5.3 CA(证书颁发机构) 的作用
CA 的工作流程:
───────────────────────────────────────
1. 网站向 CA 申请证书
Example Inc: "我是 example.com 的所有者,
这是我的公钥,请给我颁发证书"
2. CA 验证身份
├─ 验证域名所有权(发邮件/DNS记录)
├─ 验证公司身份(营业执照)
└─ 确认申请者确实拥有私钥
3. CA 创建证书内容
┌─────────────────────────┐
│ 域名: example.com │
│ 公钥: [网站公钥] │
│ 有效期: 1年 │
│ ... │
└─────────────────────────┘
4. CA 用自己的私钥签名
证书内容 ──> 计算摘要 ──> 用CA私钥加密摘要
5. 颁发最终证书
[证书内容] + [CA签名] ──> 完整证书
六、证书验证流程
6.1 浏览器如何验证证书
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
完整验证流程
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
步骤 1: 检查域名
─────────────────────────────────
浏览器访问: https://www.example.com
证书上的域名: www.example.com
✓ 域名匹配
步骤 2: 检查有效期
─────────────────────────────────
证书有效期: 2024-01-01 到 2025-01-01
当前时间: 2024-06-15
✓ 在有效期内
步骤 3: 验证证书链
─────────────────────────────────
证书链结构:
┌─────────────────────────────────┐
│ www.example.com 的证书 │ ← 网站证书
│ 颁发者: DigiCert SHA2 CA │
└─────────────┬───────────────────┘
│ 谁颁发的?
↓
┌─────────────────────────────────┐
│ DigiCert SHA2 CA 的证书 │ ← 中间证书
│ 颁发者: DigiCert Root CA │
└─────────────┬───────────────────┘
│ 谁颁发的?
↓
┌─────────────────────────────────┐
│ DigiCert Root CA 的证书 │ ← 根证书
│ 颁发者: 自己(自签名) │
│ ✓ 这个证书内置在浏览器/操作系统中 │
└─────────────────────────────────┘
验证逻辑:
我信任 Root CA
→ Root CA 信任 SHA2 CA
→ SHA2 CA 信任 example.com
→ 所以我信任 example.com
✓ 证书链完整且可信
步骤 4: 验证签名
─────────────────────────────────
验证 example.com 证书上的签名:
① 提取证书内容
内容 = [域名、公钥、有效期等]
② 计算证书摘要
摘要A = Hash(证书内容)
③ 用CA的公钥解密签名
签名值 ──> 用DigiCert SHA2 CA的公钥解密 ──> 摘要B
④ 比较两个摘要
摘要A == 摘要B ?
✓ 相等 → 证书未被篡改
✗ 不等 → 证书被篡改,拒绝连接
✓ 签名有效
步骤 5: 检查吊销状态
─────────────────────────────────
查询: 这个证书是否被CA提前吊销?
方式1: CRL (证书吊销列表)
├─ 下载CA维护的吊销列表
└─ 检查证书序列号是否在列表中
方式2: OCSP (在线证书状态协议)
├─ 实时查询CA服务器
└─ 更快更新
✓ 证书未被吊销
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
全部验证通过!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
浏览器显示: 🔒 安全
6.2 签名验证原理
CA 签名过程:
─────────────────────────────────
证书内容
↓
计算Hash摘要
↓
[摘要值: a3f8d29c...]
↓
用CA私钥加密
↓
[签名值: 3e4f5a9c...]
↓
放入证书
浏览器验证过程:
─────────────────────────────────
从证书提取:
├─ 证书内容
└─ 签名值
路径1: 计算摘要
证书内容 ──> Hash ──> 摘要A
路径2: 解密签名
签名值 ──> 用CA公钥解密 ──> 摘要B
比较:
摘要A == 摘要B ?
✓ 是 → 证书有效
✗ 否 → 证书被篡改
为什么安全?
─────────────────────────────────
攻击者想伪造证书:
1. 修改证书内容
├─ 把域名改成 fake.com
└─ 把公钥改成自己的
2. 需要重新签名
├─ 计算新的摘要
└─ 需要用CA私钥加密
3. ❌ 问题: 攻击者没有CA私钥!
└─ 无法生成有效签名
4. 浏览器验证时
├─ 用CA公钥解密签名
├─ 得到的摘要不匹配
└─ 拒绝连接!
七、完整流程总结
7.1 HTTPS 连接的完整过程
┌─────────────────────────────────────────────────┐
│ 第一阶段: 证书验证 (确认服务器身份) │
└─────────────────────────────────────────────────┘
客户端 服务器
| |
| ① 请求连接 |
|──────────────────────────────────>|
| |
| ② 发送证书 |
|<──────────────────────────────────|
| |
| ③ 验证证书 |
| - 域名匹配? |
| - 有效期OK? |
| - CA签名有效? |
| - 证书链完整? |
| ✓ 全部通过 |
| |
┌─────────────────────────────────────────────────┐
│ 第二阶段: 密钥协商 (建立对称密钥) │
└─────────────────────────────────────────────────┘
| ④ 从证书提取服务器公钥 |
| |
| ⑤ 生成预主密钥 |
| - 客户端生成随机数 |
| - 用服务器公钥加密 |
| |
| [加密的预主密钥] |
|──────────────────────────────────>|
| |
| | ⑥ 用私钥解密
| | 获得预主密钥
| |
| ⑦ 双方计算对称密钥 |
| 对称密钥 = 函数( |
| 客户端随机数, |
| 服务器随机数, |
| 预主密钥 |
| ) |
| |
┌─────────────────────────────────────────────────┐
│ 第三阶段: 加密通信 (传输实际数据) │
└─────────────────────────────────────────────────┘
| ⑧ 发送加密数据 |
| HTTP请求 → 对称加密 → 密文 |
|──────────────────────────────────>|
| |
| | ⑨ 解密处理
| | 密文 → 对称解密 → HTTP请求
| | 处理请求
| |
| ⑩ 加密响应 |
| 密文 ← 对称加密 ← HTTP响应 |
|<──────────────────────────────────|
| |
| ⑪ 解密 |
| 密文 → 对称解密 → HTTP响应 |
| |
| 后续所有通信用对称密钥加密 |
|<═════════════════════════════════>|
7.2 关键流程图
开始访问 HTTPS 网站
↓
┌──────────────────────┐
│ 建立 TCP 连接 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ TLS 握手开始 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ 服务器发送证书 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ 浏览器验证证书 │
│ - 域名 │
│ - 有效期 │
│ - CA签名 │
│ - 证书链 │
└──────────┬───────────┘
↓
┌──────┴──────┐
│ 证书有效? │
└──┬───────┬──┘
有效 │ │ 无效
↓ ↓
┌──────────┐ └──> ❌ 显示警告
│ 提取公钥 │ 中断连接
└─────┬────┘
↓
┌──────────────────────┐
│ 生成预主密钥 │
│ 用公钥加密发送 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ 服务器用私钥解密 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ 双方计算对称密钥 │
└──────────┬───────────┘
↓
┌──────────────────────┐
│ 用对称密钥加密通信 │
│ 🔒 安全连接建立 │
└──────────┬───────────┘
↓
开始传输数据
八、三种加密方式对比
┌────────────┬─────────────┬─────────────┬─────────────┐
│ 维度 │ 对称加密 │ 非对称加密 │ HTTPS混合 │
├────────────┼─────────────┼─────────────┼─────────────┤
│ 密钥 │ 1个密钥 │ 2个密钥 │ 两种都用 │
│ │ (加密解密同) │ (公钥+私钥) │ │
├────────────┼─────────────┼─────────────┼─────────────┤
│ 速度 │ 快 ⚡⚡⚡ │ 慢 🐌 │ 最优 ⚡⚡ │
├────────────┼─────────────┼─────────────┼─────────────┤
│ 密钥分发 │ 困难 ❌ │ 简单 ✓ │ 解决 ✓ │
├────────────┼─────────────┼─────────────┼─────────────┤
│ 适用场景 │ 大量数据 │ 少量数据 │ 所有场景 │
│ │ 密钥交换后 │ 密钥交换 │ │
├────────────┼─────────────┼─────────────┼─────────────┤
│ 实际使用 │ 不单独使用 │ 不单独使用 │ HTTPS采用 │
└────────────┴─────────────┴─────────────┴─────────────┘
九、总结记忆图
┌─────────────────────────────────────────────────┐
│ HTTPS 加密体系完整架构 │
└─────────────────────────────────────────────────┘
用户访问网站
↓
┌────────────────────────┐
│ 1. 证书验证阶段 │
│ (解决身份问题) │
└────────┬───────────────┘
↓
服务器发送数字证书
↓
┌────────────────────┐
│ 证书包含: │
│ ├─ 域名 │
│ ├─ 公司信息 │
│ ├─ 服务器公钥 │
│ └─ CA的数字签名 │
└────────┬───────────┘
↓
浏览器验证证书
↓
┌────────────────────┐
│ 验证项: │
│ ├─ 域名匹配? │
│ ├─ 未过期? │
│ ├─ CA可信? │
│ └─ 签名有效? │
└────────┬───────────┘
↓
全部通过 ✓
↓
┌────────────────────────┐
│ 2. 密钥协商阶段 │
│ (建立加密通道) │
└────────┬───────────────┘
↓
客户端生成预主密钥
↓
用服务器公钥加密
(非对称加密 - 慢但安全)
↓
服务器用私钥解密
↓
双方计算对称密钥
↓
┌────────────────────────┐
│ 3. 加密通信阶段 │
│ (传输实际数据) │
└────────┬───────────────┘
↓
用对称密钥加密所有数据
(对称加密 - 快速高效)
↓
┌────────────────────────┐
│ 安全通信建立! 🔒 │
│ ├─ 防窃听 ✓ │
│ ├─ 防篡改 ✓ │
│ └─ 防冒充 ✓ │
└────────────────────────┘
这就是 HTTPS 加密的完整工作流程!核心就是三个阶段:
- 证书验证 - 确认是真网站
- 密钥协商 - 安全地建立加密通道 (用非对称加密)
- 加密通信 - 快速传输数据 (用对称加密)