HTTPS 与 SSL/TLS

HTTP 明文传输,任何人都能偷看、篡改。HTTPS 把 HTTP 包装一层加密,让通信变得机密、完整、可认证。这一章把 HTTPS 拆开看清楚。

1. HTTP 的三大安全隐患

HTTPS 同时解决这三件事:加密防窃听、完整性校验防篡改、证书防伪造

2. HTTPS 不是新协议

HTTPS = HTTP over TLS。HTTP 报文不变,只是在传给 TCP 之前先经过 TLS 加密层。默认端口从 80 变成 443。

# HTTP vs HTTPS — 协议栈对比
# HTTP:  应用层 (HTTP)     → 直接走 TCP,默认端口 80
# HTTPS: 应用层 (HTTP)     → TLS 加密层  → TCP,默认端口 443
#
# HTTPS 不是新协议,是 "HTTP over TLS"
# 报文格式一模一样,只是字节被加密了再传

curl http://example.com/    # 走 80,明文
curl https://example.com/   # 走 443,加密

3. SSL vs TLS:叫法问题

SSL(Secure Sockets Layer)是网景 1995 年发明的,TLS(Transport Layer Security)是 IETF 在 SSL 3.0 基础上做的标准化版本(1999 起)。两者其实是同一东西的不同代。SSL 2/3 已被发现严重漏洞全部废弃,现在用的全是 TLS(TLS 1.2 / 1.3)。但叫法上"SSL 证书"这个习惯说法沿用至今,技术文档里通常指 TLS 证书。

4. 对称 vs 非对称加密

理解 TLS 必须先懂两种加密:

# 为什么 TLS 同时用两种加密?
# 非对称加密 (RSA/ECC):
#   - 有公钥/私钥对
#   - 公钥加密,只有私钥能解 (或反之)
#   - 慢,但能安全交换密钥
# 对称加密 (AES):
#   - 双方共享一个密钥
#   - 快,适合大量数据
#   - 但如何安全传递这个密钥? → 用非对称加密传

# TLS 把两者结合:
#   1. 用非对称加密安全协商出一个对称密钥 (pre-master secret)
#   2. 之后通信用这个对称密钥 (快)
#   "用非对称换密钥,用对称传数据"

TLS 的核心思路就是"用非对称换密钥,用对称传数据"

5. TLS 握手流程

HTTPS 通信前要先握手协商出对称密钥。简化流程:

# TLS 1.2 握手流程 (简化版)
# 1. ClientHello: 客户端说"我支持这些加密套件,这是我的随机数 A"
Client → Server: TLS版本, 支持的密码套件, 客户端随机数

# 2. ServerHello + 证书: 服务器选定套件,返回证书 + 随机数 B
Server → Client: 选定的套件, 服务器随机数, X.509 证书 (含公钥)

# 3. 客户端验证证书 (见下文)
# 4. 客户端生成 pre-master secret,用服务器公钥加密发过去
Client → Server: 加密后的 pre-master secret

# 5. 双方用 (A + B + pre-master) 算出对称会话密钥
# 6. 后续所有数据用这个对称密钥加解密 — 这就是 "对称加密传输"

# TLS 1.3 简化为 1 个 RTT (甚至 0-RTT),更快更安全

关键点:

6. 证书:证明服务器身份

光加密不够——如果黑客冒充银行给你他的公钥,你加密的内容他全能解。数字证书解决"我怎么知道这个公钥真是银行的"问题。

证书由CA(Certificate Authority,证书颁发机构)签发,是一份带签名的电子文档:

# X.509 证书长什么样
# 一份证书包含:
Certificate:
    Version: 3
    Serial Number: 0x...
    Signature Algorithm: sha256WithRSAEncryption
    Issuer: CN=Let's Encrypt R3       # 谁签发的
    Validity:
        Not Before: Aug  5 06:00:00 2026 GMT
        Not After : Nov  3 06:00:00 2026 GMT   # 90 天后过期
    Subject: CN=fertijourney.com      # 给谁签的
    Subject Public Key Info:          # 持有人的公钥
        Public Key Algorithm: id-ecPublicKey
        ...
    X509v3 Subject Alternative Name:
        DNS:fertijourney.com, DNS:www.fertijourney.com
    Signature Algorithm: sha256WithRSAEncryption
        (CA 用私钥对前面内容的签名)

# 浏览器验证: 拿 CA 的公钥验签名 → 通过则信任

7. 信任链:根 CA

浏览器/操作系统内置了一份信任的根 CA 列表。你的证书只要被这条链上某个 CA 签发,浏览器就信任:

# 证书信任链
# 你的证书
#   ↑ 签发者
# 中间 CA 证书 (如 Let's Encrypt R3)
#   ↑ 签发者
# 根 CA 证书 (如 ISRG Root X1)
#   ↑ 操作系统/浏览器内置信任

# 浏览器/操作系统自带一个根 CA 列表 (信任根)
# 你的证书只有被这条链上的某个 CA 签发,才会被信任
# 配置服务器时,通常要 "证书 + 中间证书" 一起发,否则部分客户端会不认

# 查看一个网站的证书链:
openssl s_client -connect fertijourney.com:443 -showcerts

自签名证书(自己当 CA 签自己)浏览器不认,会弹"不安全"警告——适合内网开发用。

8. Let's Encrypt:免费证书

2015 年前 SSL 证书要钱,而且贵。Let's Encrypt 出现后完全免费(90 天有效期,自动续期),是个人/小项目首选:

# Let's Encrypt — 免费证书 (90 天有效期)
# 用 certbot 自动申请 + 自动续期:
sudo apt install certbot
sudo certbot certonly --nginx -d fertijourney.com -d www.fertijourney.com

# 证书放在:
#   /etc/letsencrypt/live/fertijourney.com/fullchain.pem  (含中间证书)
#   /etc/letsencrypt/live/fertijourney.com/privkey.pem    (私钥)

# Nginx 配置:
server {
    listen 443 ssl http2;
    server_name fertijourney.com;
    ssl_certificate     /etc/letsencrypt/live/fertijourney.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/fertijourney.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
}

# 自动续期 (cron 里加):
sudo certbot renew --quiet

9. 证书的类型

10. TLS 1.3:更快更安全

2018 年标准化的 TLS 1.3 带来:

新项目务必启用 TLS 1.2 和 1.3,禁用 TLS 1.0/1.1 和 SSL。

11. HSTS:防首次劫持

即使用了 HTTPS,用户第一次输入 http:// 时仍会先发 HTTP(可能被劫持)。HSTS 告诉浏览器"以后永远 HTTPS":

# HSTS — 强制 HTTPS
# 服务器响应头告诉浏览器: "我以后永远用 HTTPS 访问我"
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

# max-age=31536000      一年内强制 HTTPS
# includeSubDomains     所有子域名也强制
# preload               申请加入浏览器内置的 HSTS Preload 列表
#                        (即便用户第一次访问也是 HTTPS,防止首次劫持)

# 警告: 开启 HSTS 前要确认 HTTPS 完全可用,否则用户可能永远访问不到你

# 把 http 强制跳转 https:
# 1. 服务器 301 跳转 (处理用户输入 http:// 的情况)
# 2. HSTS (处理浏览器以后的访问)

12. HTTPS 性能影响

早期 HTTPS 慢,但现代硬件上几乎可以忽略

13. 调试 HTTPS

小结

HTTPS = HTTP + TLS。用非对称加密换对称密钥,用对称密钥传数据,用 CA 证书证明身份。新项目一律 HTTPS + TLS 1.2/1.3 + HSTS + Let's Encrypt,没有任何借口不用。

← 上一篇 Cookie 与 Session

下一篇 curl 命令实战

✈️💬