地址栏里那把"小锁"背后,是一套精密的密码学流程——TLS 握手。它让浏览器和服务器在公开网络上安全地协商出加密密钥,从此传输内容只有双方能看懂。本文逐步拆解 HTTPS 的加密原理与 TLS 1.3 的握手全过程。
1. 为什么需要 HTTPS
HTTP 是明文传输,数据经过的每个路由器、运营商、Wi-Fi 热点都可能被偷看甚至篡改。HTTPS 在 HTTP 外面套了一层 TLS 加密,提供三大保障:
- 机密性:内容加密,中间人无法读取。
- 完整性:任何篡改都会被接收方发现。
- 身份认证:确认你连的确实是目标服务器,而不是钓鱼站点。
2. 两种加密算法
TLS 混合使用了两种加密体系:
- 非对称加密(RSA、ECDSA):公钥加密、私钥解密,安全但慢,只用于握手阶段。
- 对称加密(AES、ChaCha20):双方用同一个密钥,速度快,用于实际数据传输。
握手的本质,就是用非对称加密安全地交换出一个对称密钥。
3. TLS 1.3 握手流程
相比 TLS 1.2 需要两次往返,1.3 把握手压缩到一次往返:
- 客户端发送
ClientHello:支持的 TLS 版本、加密套件列表,以及一个随机数。 - 服务端回复
ServerHello:选定加密套件,同时发送证书和密钥交换参数。 - 客户端验证证书链,并计算出"预主密钥",双方各自推导出相同的会话密钥。
- 客户端发送
Finished,此后所有应用数据都用会话密钥加密。
整个过程中,私钥从未在网络上传输,窃听者即使拿到全部报文也算不出密钥。
4. 证书与信任链
服务器证书由 CA(Certificate Authority)签发。浏览器内置了根证书库,验证时沿着"服务器证书 → 中间证书 → 根证书"逐级校验签名,只要有一环不信任,页面就会报警。
证书有效期通常为 90 天到 1 年,到期前必须续期,否则用户会看到"连接不安全"的红色警告。
5. 用 openssl 亲眼观察
# 建立 TLS 连接并打印证书链
openssl s_client -connect example.com:443 -showcerts
# 只看证书的签发者与有效期
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -issuer -dates
# 查看站点支持的 TLS 版本
openssl s_client -connect example.com:443 -tls1_3
输出里的 subject 是证书持有人,issuer 是签发它的 CA,notAfter 是过期时间。
6. 常见问题排查
# 证书过期?用 curl 查看报错
curl -v https://example.com
# 强制忽略证书错误(仅测试用,切勿用于生产)
curl -k https://example.com
# 检查证书链是否完整
openssl verify -CAfile ca.pem server.crt
- 报
certificate has expired:证书过期,联系运维续期。 - 报
self-signed certificate:证书未受信任,检查是否安装了正确的 CA。 - 报
mixed content:页面里仍引用了 http:// 资源,浏览器会拦截。
💡 学习建议:申请一个免费的 Let's Encrypt 证书,把自己网站的 HTTPS 从零配通一次。证书申请、部署、自动续期全流程走一遍,比只看文章理解深十倍。