HTTPS 到底怎么保证安全的?

本文最后更新于: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 聪明地结合了两者的优势:

  1. 非对称加密:安全地交换对称密钥
  2. 对称加密:用交换的密钥加密实际传输的数据

这样又快又安全。

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)

验证过程:

  1. 检查服务器证书过期没
  2. 检查域名对不对
  3. 用中间 CA 公钥验证服务器证书签名
  4. 用根 CA 公钥验证中间 CA 证书
  5. 根 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
# 装 Certbot
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;

# HSTS(强制 HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;

location / {
root /var/www/html;
index index.html;
}
}

# HTTP 重定向到 HTTPS
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 等

HTTPS 到底怎么保证安全的?
http://bestkele.com/2020/06/02/concept/Https-principle/
作者
kele
发布于
2020年6月2日
许可协议