HTTPS 的「秘钥交换 + 证书校验」全流程_秘钥证书
HTTPS 通过「证书像身份证、密钥交换像一次临时暗号本的当面约定」的握手流程,实现了“我是谁+对话只让你看”双重保障。
全流程图解
分步详解
一、密钥交换(Key Exchange)
-
ClientHello
-
客户端生成随机数
A
(32字节) -
发送支持的密码套件列表(如
TLS_AES_128_GCM_SHA256
) -
发送 客户端公钥(基于椭圆曲线
x25519
生成临时密钥对)
-
-
ServerHello
-
服务器生成随机数
B
(32字节) -
选定密码套件(如
TLS_AES_256_GCM_SHA384
) -
发送 服务器公钥(临时密钥对)
-
关键安全机制:
-
使用 ECDHE 算法(椭圆曲线迪菲-赫尔曼)实现前向保密(FS)
-
会话密钥公式:
会话密钥 = PRF(A + B, ECDHE(客户端私钥, 服务器公钥))
-
-
💡 前向保密(FS)的意义:即使服务器私钥泄露,历史会话也无法被解密!
二、证书校验(Certificate Verification)
-
服务器发送证书链
Certificate Chain: - Leaf Certificate(叶子证书:example.com) - Intermediate CA(中间证书:R3) - Root CA(根证书:ISRG Root X1)
-
客户端逐级验证
-
签名验证: 用上级 CA 公钥验证下级证书签名(根证书公钥内置于操作系统)
-
有效期检查: 确认证书在
Validity Period
内(如 Let\'s Encrypt 有效期为 90 天) -
域名匹配: 检查证书的
Subject Alternative Name (SAN)
是否包含请求域名 -
吊销状态: 通过 OCSP Stapling(服务器返回吊销状态)或 CRL 列表检查
-
⚠️ 若校验失败(如域名不匹配/证书过期),浏览器显示
NET::ERR_CERT_INVALID
。
三、会话密钥生成
-
客户端计算:
-
输入:随机数
A
+B
+ ECDHE 共享密钥shared_secret
-
输出:生成 主密钥(Master Secret)
-
派生:
客户端写密钥 = HKDF-Expand(Master Secret, \"client key\")服务器写密钥 = HKDF-Expand(Master Secret, \"server key\")
-
-
服务器计算:
-
相同输入 → 相同密钥(无需传输密钥本身)
-
🔒 加密通信开始:后续所有数据用 AES-GCM 等对称算法加密传输。
四、握手完成(Finished)
-
客户端发送
Finished
消息(包含所有握手消息的 HMAC 摘要) -
服务器验证摘要 → 返回自己的
Finished
消息 -
安全意义:确认握手过程未被篡改(防中间人攻击)
⚡ TLS 1.3 优化亮点
⚠️ 关键安全风险与规避
-
0-RTT 重放攻击
-
风险:攻击者重放 0-RTT 数据(如支付请求)
-
规避:仅对幂等操作(如 GET)启用 0-RTT
-
-
证书透明(Certificate Transparency)
-
风险:CA 错误签发证书不被察觉
-
方案:证书必须提交公共日志(如 Google CT)
-
-
中间人攻击(MITM)
-
防御:严格证书校验 + HSTS 强制 HTTPS
-
🔍 调试工具
-
Wireshark 抓包分析
tcp.port == 443 && ssl.handshake.type == 1 # 过滤 ClientHello
https://example.com/wireshark-tls.png
-
OpenSSL 命令测试
openssl s_client -connect example.com:443 -tls1_3 -status# 输出证书链/OCSP 状态/协商算法
💎 总结:HTTPS 安全基石
📌 部署建议:
优先启用 TLS 1.3(Nginx 配置
ssl_protocols TLSv1.3;
)使用 ECDSA 证书(比 RSA 更高效安全)
开启 OCSP Stapling 加速证书吊销检查