本文最后更新于:2026年2月12日 凌晨
HTTPS 到底怎么保证安全的?
HTTP 传数据是明文的,早年间互联网没啥敏感业务,凑合用还行。后来电商、网银这些东西出来了,数据安全就成了刚需。HTTPS 就是在 HTTP 外面套了层加密,让数据从”明信片”变成了”密封信封”。
为啥非得用 HTTPS?
HTTP 有多危险?
想象一下,你在咖啡馆蹭 WiFi 网购:
1 2 3 4 5 6
| 你的电脑 ──明文数据──► 路由器 ──明文数据──► 服务器 ↑ 攻击者随便截: - 银行卡号:6222 **** **** 8888 - 密码:mysecret123 - 收货地址:北京市xxx
|
HTTP 就像用透明信封寄信,中间谁都能拆开看。
HTTPS 怎么保护的?
1 2 3 4 5
| 你的电脑 ──密文数据──► 路由器 ──密文数据──► 服务器 ↑ 攻击者截到的是乱码: - a9f3b2c1d8e7f6... - 根本看不懂
|
HTTPS 通过加密确保三件事:
- 机密性:只有通信双方能看懂
- 完整性:数据没被篡改过
- 身份验证:确认对方是真的,不是冒牌货
加密是怎么玩的?
对称加密:一把钥匙开一把锁
加密解密用同一把密钥:
1 2 3 4 5 6 7
| 明文 + 密钥 ──加密──► 密文 密文 + 密钥 ──解密──► 明文
例子: 明文: "Hello" 密钥: "secret" 密文: "Xj92#mK"
|
优点:速度快,适合加密大量数据
缺点:密钥怎么给对方?传密钥的时候被截了就全完了
常用算法:AES、DES、3DES、ChaCha20
非对称加密:公钥私钥配对
用一对密钥——公钥和私钥:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ┌─────────────────────────────────────┐ │ 生成密钥对 │ │ 公钥:谁都能知道 │ │ 私钥:自己藏着,谁也别给 │ └─────────────────────────────────────┘
加密过程: 明文 + 公钥 ──加密──► 密文 密文 + 私钥 ──解密──► 明文
或者反过来: 明文 + 私钥 ──加密──► 密文 密文 + 公钥 ──解密──► 明文
|
核心特性:
- 公钥加密的数据,只有对应私钥能解
- 私钥加密的数据,只有对应公钥能解
- 从公钥推不出私钥
优点:解决了密钥分发问题
缺点:速度慢,不适合加密大量数据
常用算法:RSA、ECDSA、DH
混合加密:各取所长
HTTPS 聪明地结合了两者的优势:
- 非对称加密:安全地交换对称密钥
- 对称加密:用交换的密钥加密实际传输的数据
这样又快又安全。
HTTPS 通信全过程
HTTPS = HTTP + TLS/SSL,端口从 80 变成了 443。
简化的握手过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 客户端 服务器 │ │ │ ────── ClientHello ───────────► │ 支持的加密套件、随机数 │ │ │ ◄───── ServerHello ──────────── │ 选定的加密套件、随机数 │ ◄───── Certificate ──────────── │ 服务器证书(含公钥) │ ◄───── [ServerKeyExchange] ──── │ (部分密钥交换需要) │ ◄───── ServerHelloDone ──────── │ │ │ │ ────── ClientKeyExchange ─────► │ 预主密钥(用公钥加密) │ ────── [ChangeCipherSpec] ────► │ 通知后续使用加密 │ ────── Finished ──────────────► │ 握手完成验证 │ │ │ ◄───── [ChangeCipherSpec] ───── │ 通知后续使用加密 │ ◄───── Finished ─────────────── │ 握手完成验证 │ │ │ ═══════════════════════════════ │ 加密通信开始 │ │
|
详细步骤拆解
第 1 步:ClientHello
客户端告诉服务器:我支持哪些 TLS 版本、加密套件、压缩算法,顺便发个随机数。
1 2 3 4 5 6
| TLS 版本: TLS 1.3 加密套件: - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - TLS_AES_128_GCM_SHA256 随机数: 0x5f8a2b...
|
第 2 步:ServerHello + Certificate
服务器选好加密套件,把证书(含公钥)和随机数发回来。
第 3 步:密钥交换
客户端生成一个预主密钥(Pre-Master Secret),用服务器公钥加密后发过去:
1 2
| 客户端生成随机数: 0x9c4d7e... 用服务器公钥加密后发送
|
服务器用私钥解密,拿到预主密钥。
第 4 步:生成会话密钥
双方用三个随机数算出会话密钥:
- ClientHello 随机数
- ServerHello 随机数
- 预主密钥
1 2 3 4
| 主密钥 = PRF(预主密钥, "master secret", ClientHello.random + ServerHello.random)
会话密钥从主密钥派生,用来加密后续通信
|
第 5 步:完成握手
双方发 Finished 消息验证握手过程没被篡改,之后所有通信都用会话密钥加密。
数字证书:怎么证明你是你?
没有证书会咋样?
假设攻击者冒充服务器:
1 2 3 4 5
| 客户端 ──► 中间人(冒充服务器)──► 真实服务器 ↑ 返回假公钥 客户端用假公钥加密 中间人可以解密偷数据
|
数字证书就是用来证明”这个公钥确实是这个网站的”。
证书里都有啥?
1 2 3 4 5 6 7 8 9 10
| 证书内容: ├─ 版本号 ├─ 序列号 ├─ 签名算法 ├─ 颁发者(CA)信息 ├─ 有效期 ├─ 主体(域名)信息 ├─ 主体公钥 ├─ 扩展信息(SAN、密钥用途等) └─ 签名(CA 用私钥对以上内容签名)
|
证书链验证
1 2 3 4 5 6 7
| 根 CA 证书(内嵌在操作系统/浏览器里) │ ▼ 签名 中间 CA 证书 │ ▼ 签名 服务器证书(example.com)
|
验证过程:
- 检查服务器证书过期没
- 检查域名对不对
- 用中间 CA 公钥验证服务器证书签名
- 用根 CA 公钥验证中间 CA 证书
- 根 CA 证书在信任列表里 → 验证通过
证书类型
| 类型 |
验证内容 |
价格 |
适合场景 |
| DV(域名验证) |
域名所有权 |
免费-便宜 |
个人博客、小企业 |
| OV(组织验证) |
域名+组织信息 |
中等 |
企业官网 |
| EV(扩展验证) |
严格组织审查 |
贵 |
银行、金融机构 |
TLS 版本迭代
| 版本 |
年份 |
主要改进 |
| SSL 1.0 |
1994 |
从没正式发布 |
| SSL 2.0 |
1995 |
已废弃(不安全) |
| SSL 3.0 |
1996 |
已废弃(POODLE 攻击) |
| TLS 1.0 |
1999 |
基于 SSL 3.0 改进 |
| TLS 1.1 |
2006 |
增强 CBC 安全 |
| TLS 1.2 |
2008 |
增加 AEAD 加密 |
| TLS 1.3 |
2018 |
简化握手,增强安全 |
TLS 1.3 的改进:
- 握手从 2-RTT 减少到 1-RTT(甚至 0-RTT)
- 干掉不安全的加密算法
- 前向安全性更强
实际应用
搞个免费证书(Let’s Encrypt)
1 2 3 4 5 6 7 8
| sudo apt install certbot
sudo certbot certonly --standalone -d example.com
sudo certbot renew --dry-run
|
Nginx 配置 HTTPS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers off; add_header Strict-Transport-Security "max-age=63072000" always; location / { root /var/www/html; index index.html; } }
server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; }
|
常见问题
Q: HTTPS 就一定安全吗?
HTTPS 保的是传输过程,不保网站本身。服务器要是被黑了,HTTPS 也拦不住数据泄露。
Q: 为啥有的网站显示”不安全”?
- 证书过期了
- 证书和域名不匹配
- 用了自签名证书
- 混着加载 HTTP 资源(HTTPS 页面里夹 HTTP 图片/JS)
Q: HTTPS 会不会拖慢网站?
现代硬件 + TLS 1.3 优化,HTTPS 的额外开销基本可以忽略。而且 HTTP/2 只能用在 HTTPS 上,用了反而可能更快。
tips
| 特性 |
HTTP |
HTTPS |
| 安全性 |
明文传输 |
加密传输 |
| 端口 |
80 |
443 |
| 身份验证 |
没有 |
证书验证 |
| 数据完整性 |
没保障 |
防篡改 |
| SEO 排名 |
正常 |
略优 |
| 现代特性支持 |
有限 |
HTTP/2、Service Worker 等 |