HTTPS 与 TLS 握手
涵盖 HTTPS 概念、对称加密 vs 非对称加密、TLS 1.2 与 1.3 握手流程、CA 证书、SSL 与 TLS 的关系、混合加密的工程实践。
一、HTTP vs HTTPS
1. 基本概念
HTTP(HyperText Transfer Protocol):
- 明文传输,端口 80
- 数据不加密,可以被窃听、篡改
HTTPS(HTTP Secure):
- HTTP + TLS(传输层安全)
- 端口 443
- 加密传输,防止窃听;校验完整性,防止篡改;身份认证,防止冒充2. HTTPS 的三大作用
1. 数据保密性:通过加密防止被窃听
2. 数据完整性:MAC 校验防止被篡改
3. 身份认证:CA 证书验证服务器身份,防止被冒充3. HTTPS 协议栈
┌─────────────────────┐
│ HTTP 协议 │ ← 应用层
├─────────────────────┤
│ TLS 协议 │ ← HTTP/1.1、HTTP/2 通常在 TCP 之上
├─────────────────────┤
│ TCP 协议 │ ← 传输层
├─────────────────────┤
│ IP 协议 │ ← 网络层
└─────────────────────┘
HTTP/3 是例外:它运行在基于 UDP 的 QUIC 上,TLS 1.3 握手能力集成在 QUIC 中。二、加密基础
1. 对称加密
特点:加密和解密使用同一个密钥
常见算法:DES、3DES、AES、ChaCha20
优点:
- 速度快(适合大数据量加密)
- 适合数据加密
缺点:
- 密钥传输不安全(怎么把密钥给对方?)
- 多人通信需要维护多个密钥对
示意:
明文 --[密钥 K]--> 密文
密文 --[密钥 K]--> 明文2. 非对称加密
特点:加密和解密使用不同密钥(公钥 + 私钥)
常见体系:RSA;基于椭圆曲线的加密/签名方案;DH/ECDH 密钥协商。DH/ECDH 是密钥协商机制,不是“用公钥加密、私钥解密”的加密算法。
公钥:公开,任何人都可以拿到
私钥:保密,只有拥有者知道
用法 1(加密通信):
公钥加密 → 私钥解密(任何人都能发消息,只有私钥持有者能读)
明文 --[公钥]--> 密文
密文 --[私钥]--> 明文
用法 2(数字签名):
私钥签名 → 公钥验证(证明消息确实是私钥持有者发的)
签名 --[公钥]--> 验证通过/失败
优点:
- 公钥可以公开传输,私钥保密
- 解决密钥分发问题
缺点:
- 计算成本通常显著高于对称加密,具体差距取决于算法、参数、硬件与操作类型
- 不适合加密大量数据3. 混合加密(工程实践)
实际 TLS 用法(混合密码系统):
1. 握手中通过认证和密钥协商建立共享秘密;现代 TLS 通常使用(EC)DHE 协商,而不是直接传输会话密钥
2. 用对称加密传输数据(解决速度问题)
完整流程:
- 客户端与服务端交换临时密钥协商参数,并验证服务端证书与签名
- 双方各自计算相同的共享秘密,再派生流量密钥
- 后续通信使用派生出的对称密钥进行认证加密4. 摘要算法 / 哈希算法
特点:单向函数,不可逆(理论上)
常见算法:MD5(已被攻破)、SHA-1(已被攻破)、SHA-256、SHA-3
用途:
- 验证数据完整性(发送方算 hash,接收方重算,对比)
- 密码存储(使用带随机盐、成本可调的专用密码哈希/KDF,如 Argon2、scrypt、bcrypt 或 PBKDF2;不能直接存普通 SHA-256)
- 数字签名(先 hash 再签名)
注意:hash 不是加密!加密是可逆的,hash 是不可逆的5. 数字签名
过程:
1. 发送方:对消息算 hash(hash M = H(M))
2. 发送方:使用私钥和签名算法对摘要或消息生成签名
3. 发送方:发送消息 M + 签名 S
4. 接收方:使用发送方公钥和对应签名算法验证签名
5. 签名算法结合收到的消息摘要判断验证是否通过
6. 相同 → 消息完整且确实是发送方发的三、TLS 握手流程
1. TLS 1.2 完整握手(以旧式 RSA 密钥交换为例)
客户端 服务端
│ │
│──────── ① ClientHello ────────────────────────────→│
│ - 支持的 TLS 版本 │
│ - 客户端随机数 (client random) │
│ - 客户端支持的密码套件 │
│ - Session ID(如果有) │
│ │
│←──────── ② ServerHello ───────────────────────────│
│ - 选定的 TLS 版本 │
│ - 服务端随机数 (server random) │
│ - 选定的密码套件 │
│ - Session ID │
│ │
│←──────── ③ Certificate ───────────────────────────│
│ - 服务器证书链 │
│ - 包含公钥 │
│ │
│←──────── ④ ServerHelloDone ───────────────────────│
│ │
│ │
│ 客户端验证证书 │
│ 用服务器公钥加密 pre-master secret │
│ │
│──────── ⑤ ClientKeyExchange ──────────────────────→│
│ - 用服务器公钥加密的 pre-master secret │
│ - ChangeCipherSpec(通知后续用协商的密钥) │
│ - Finished(验证整个握手过程) │
│ │
│←──────── ⑥ ChangeCipherSpec ─────────────────────│
│ - Finished(验证整个握手过程) │
│ │
│ 双方根据 client random + server random + pre-master 计算 master secret
│ 然后派生会话密钥(用于对称加密) │
│ │
│──────── ⑦ 加密的 HTTP 数据 ─────────────────────→│
│←──────── ⑦ 加密的 HTTP 数据 ─────────────────────│该图描述的是 TLS 1.2 的 RSA 密钥交换,便于理解历史流程,但不代表所有 TLS 1.2 密码套件。采用 ECDHE 时,客户端和服务端交换临时密钥协商参数,证书私钥主要用于签名认证,并不会用来解密一个由客户端生成的 pre-master secret;ECDHE 还能提供前向保密。
图中 RSA 握手的关键点:
- 客户端发起:随机数 + 密码套件
- 服务端回应:随机数 + 选定的密码套件 + 服务器证书
- 客户端验证证书,在该 RSA 示例中用证书公钥加密 pre-master secret 发送给服务端
- 双方独立计算 master secret(用 client random + server random + pre-master)
- 验证握手:Finished 消息包含前面所有内容的 hash,防止被篡改
2. TLS 1.3 握手(简化到 1-RTT)
TLS 1.3 重大改进:
- 1-RTT(往返一次)即可建立连接
- 0-RTT(重连时),甚至零往返
- 移除了不安全的算法(MD5、SHA-1、RC4、3DES 等)
握手流程:
1. 客户端 → ClientHello:随机数 + 密码套件 + key_share(DH 公钥)
2. 服务端 → ServerHello:随机数 + 选定的套件 + 服务端 key_share
+ Certificate + CertificateVerify + Finished
3. 客户端 → Finished(响应服务端)
握手完成,后续加密通信3. TLS 1.3 关键特性
1. 前向保密(Forward Secrecy):
即使服务器私钥泄漏,之前加密的会话仍然安全
因为每次会话都用临时的 DH 公钥
2. 0-RTT:
重连时客户端可以发送"早期数据"(带 ID)
服务器解密后才能验证
⚠️ 风险:存在重放攻击可能,需谨慎使用
3. 加密更多握手信息:
ServerHello 之后的大部分握手消息(包括证书)会被加密
常规 TLS 1.3 的 ClientHello 仍是明文,因此其中的 SNI 默认可见;只有双方支持并成功使用 ECH 时才能隐藏相应 ClientHello 信息
4. 密码套件简化:
TLS 1.2: 几十种
TLS 1.3 将密钥交换与认证算法从对称密码套件名称中拆开,只保留认证加密算法和哈希组合,例如 TLS_AES_256_GCM_SHA384、TLS_AES_128_GCM_SHA256四、CA 证书
1. 为什么需要 CA
问题:客户端怎么知道服务器的公钥是真的?
如果没有 CA:
- 客户端收到服务器的公钥
- 但是中间人可以伪造公钥
- 客户端无法验证真伪
CA 解决方案:
- 服务器的公钥由权威 CA 签名认证
- 客户端信任 CA(操作系统/浏览器内置根证书)
- 客户端用 CA 的公钥验证服务器的证书签名
- 如果验证通过,说明公钥确实是服务器的2. 证书链
根 CA(自签名证书,受系统信任)
│
├── 中间 CA 1(由根 CA 签发)
│ │
│ └── 服务器证书(由中间 CA 1 签发)
│
└── 中间 CA 2(由根 CA 签发)
│
└── 服务器证书(由中间 CA 2 签发)
客户端验证服务器证书的流程:
1. 用中间 CA 的公钥验证服务器证书的签名
2. 用根 CA 的公钥验证中间 CA 证书的签名
3. 根 CA 的证书是受信任的(预装在系统中)
4. 整条链路验证通过 → 服务器可信3. 证书内容
证书 X.509 标准包含:
- 颁发者(Issuer):CA 的标识
- 主体(Subject):拥有者的域名
- 有效期(Validity):起止时间
- 公钥(Public Key):服务器公钥
- 签名(Signature):CA 对证书的签名
- 序列号(Serial Number)
- 扩展(Extensions):如 SAN(多域名)4. 自签名证书
开发环境常用 OpenSSL 生成:
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
特点:
- 自己签发自己
- 不被浏览器/系统信任
- 用于本地开发、测试
- 面向公共互联网的站点通常使用受客户端信任的公共 CA 证书;受控的内网环境也可以部署自己的私有 CA,并把根证书安全地加入客户端信任库5. HTTPS 证书生成与部署
# Let's Encrypt 免费证书(Certbot)
certbot certonly --standalone -d example.com
# Nginx 配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# HSTS(强制 HTTPS)
add_header Strict-Transport-Security "max-age=31536000" always;
}
# HTTP 重定向 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}五、SSL 与 TLS 的关系
历史:
- SSL 1.0:Netscape 1995,未发布
- SSL 2.0:1995,2011 年被禁用(不安全)
- SSL 3.0:1996,2014 年 POODLE 攻击后被弃用
- TLS 1.0(1999):基于 SSL 3.0 改进
- TLS 1.1(2006):小改进
- TLS 1.2(2008):主流协议,支持现代算法
- TLS 1.3(2018):最新版本,1-RTT、强制前向保密
现在常说的 SSL 实际就是 TLS(甚至很多公司把 HTTPS 配置叫 SSL 配置)
推荐使用 TLS 1.3 + TLS 1.2,禁用 SSL 3.0、TLS 1.0、TLS 1.1六、密码套件(Cipher Suite)
一个 TLS 密码套件字符串描述了握手和通信使用的算法:
例:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
拆解:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
└─┬─┘ └─┬──┘ └─┬┘ └────┬─────┘ └┬┘
│ │ │ │ └─ MAC 算法(SHA256)
│ │ │ └── 对称加密(AES 128 GCM)
│ │ └── 身份认证(RSA 签名)
│ └── 密钥交换(ECDHE,椭圆曲线 DH)
└── 协议(TLS)
TLS 1.3 的密码套件简化为:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256
TLS 1.3 默认所有套件都提供前向保密七、HTTPS 性能优化
1. 性能成本
HTTPS 比 HTTP 多消耗的:
- TLS 握手:1-2 个 RTT(TLS 1.3 减少到 1-RTT)
- 加解密 CPU:现代 CPU 通常有 AES-NI 指令集,影响小
- 数据膨胀:加密 + MAC 增加少量字节
优化方向:
1. TLS 1.3(1-RTT 握手)
2. Session Ticket(会话复用,避免重新握手)
3. Session ID(会话复用)
4. False Start(TLS 1.2 优化,发送 Finished 前提前发数据)
5. OCSP Stapling(避免客户端实时查证书状态)
6. 硬件加速 / Nginx + OpenSSL AES-NI2. 实际部署性能
HTTPS 优化清单:
✅ 启用 HTTP/2(多路复用,头压缩)
✅ 启用 TLS 1.3
✅ 配置会话复用(Session Ticket)
✅ 配置 HSTS(强制 HTTPS)
✅ 启用 OCSP Stapling
✅ 配置合适的密码套件
✅ 证书链完整且有效
✅ 启用 keep-alive八、面试高频问答
Q1: 介绍一下 HTTPS 握手过程?
答:HTTPS 基于 TLS 协议。以 TLS 1.2 为例:
- 客户端 → ClientHello:客户端发送支持的 TLS 版本、密码套件、客户端随机数
- 服务端 → ServerHello + Certificate + ServerHelloDone:服务端选定密码套件,发送自己的证书(含公钥),并发送服务端随机数
- 客户端验证证书:用本地根证书验证服务端证书链,确认公钥可信
- 客户端 → ClientKeyExchange + ChangeCipherSpec + Finished:客户端用服务端公钥加密 pre-master secret 发送过去,通知后续用对称密钥,并发送 Finished(包含前面所有内容的 hash)验证握手
- 服务端 → ChangeCipherSpec + Finished:服务端也通知后续用对称密钥,并发送自己的 Finished
- 双方计算 master secret:用 client random + server random + pre-master secret 计算 master secret,再派生出会话密钥
- 加密通信:后续用对称密钥加解密数据
TLS 1.3 把上述过程简化为 1-RTT,并强制使用前向保密。
Q2: 对称加密和非对称加密的区别?为什么 HTTPS 用两者?
答:
| 维度 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥 | 加解密同一密钥 | 公钥 + 私钥 |
| 速度 | 快(MB/s 量级) | 慢(KB/s 量级) |
| 应用 | 加密大量数据 | 密钥交换、签名 |
| 问题 | 密钥怎么传给对方? | 速度慢不适合大数据 |
HTTPS 用混合加密:非对称加密(RSA/ECDH)交换对称密钥,对称加密(AES/ChaCha20)加密数据。兼顾安全和性能。
Q3: 什么是 CA?证书怎么验证?
答:CA(Certificate Authority)是权威的证书颁发机构。证书验证流程:
- 服务端提供证书(包含服务端公钥、域名、有效期、CA 签名)
- 客户端用 CA 的公钥验证证书签名
- 检查证书有效期、域名是否匹配
- 检查证书是否被吊销(OCSP / CRL)
- 验证通过 → 确认服务端公钥是真的
证书链验证时,要递归验证每一级 CA 证书,直到根 CA(操作系统/浏览器内置)。
Q4: 前向保密是什么?
答:即使服务器的长期私钥泄漏,过去的加密会话仍然是安全的。原理:每次 TLS 握手用临时密钥对(DH/ECDH),协商出独立的会话密钥。长期私钥只用于身份认证,不参与会话密钥派生。即使长期私钥泄漏,也无法解密过去的会话。
TLS 1.3 强制使用支持前向保密的密码套件。
Q5: 为什么不用纯非对称加密做 HTTPS?
答:非对称加密(RSA)性能约为对称加密(AES)的 1/100 ~ 1/1000。对于大量数据(HTML/JS/CSS/图片),非对称加密会让 HTTPS 慢到不可用。混合加密方案(用非对称加密交换对称密钥 + 用对称加密数据)是最优解。
十、HTTP vs HTTPS 标准答法
30 秒标准版(必背)
HTTP 是明文传输,不安全;HTTPS = HTTP + SSL/TLS,在 HTTP 之下加了一层加密传输,核心是通过 TLS 握手协商出一个对称会话密钥,之后所有数据用这个密钥加密传输。
1 分钟进阶版(加分用)
- HTTP 端口 80,HTTPS 端口 443。
- HTTPS 在 HTTP 与 TCP 之间多了一层 TLS/SSL 协议,提供加密、完整性校验、身份认证三大能力。
- 加密方式:握手阶段通过证书签名完成身份认证,并通过 ECDHE 等机制协商共享秘密、派生密钥;应用数据阶段使用 AES-GCM、ChaCha20-Poly1305 等对称认证加密。RSA 可以用于签名,旧版 TLS 也曾支持 RSA 密钥传输;ECDHE 不是“非对称加密传输密钥”。
- 身份认证:服务器提供 TLS 证书,由 CA 机构签名,浏览器验证证书合法性。
- TLS 1.2 与 TLS 1.3 的完整握手往返次数取决于版本和握手路径;TLS 1.3 通常可在 1-RTT 后发送应用数据。0-RTT 只适用于恢复会话的早期数据,并有重放风险,不能称为完整首次握手。
十一、对称加密 vs 非对称加密
30 秒标准版(直接背)
对称加密:加密和解密用同一把密钥(如 AES)。速度快,适合大数据量加密,但密钥分发困难(如何安全地把密钥给对方)。
非对称加密:加密和解密用一对密钥(公钥 + 私钥)。公钥公开,私钥自己保留。速度慢,但解决密钥分发问题。
HTTPS 使用混合密码系统:握手阶段完成身份认证和密钥协商,双方派生对称流量密钥,再用对称认证加密保护应用数据。
1 分钟进阶版(加分用)
- 对称加密:AES、DES、3DES、ChaCha20。加密 1GB 数据只比明文慢约 1-2 倍。
- 公钥密码相关机制:RSA 可用于签名或特定加密方案,ECDSA/EdDSA 用于签名,DH/ECDH 用于密钥协商;“ECC”是椭圆曲线密码体系的统称。其成本和安全性质不能用一个固定倍数概括。
- 混合密码系统:用 ECDHE 等机制建立共享秘密并派生临时对称密钥,再用 AES-GCM 等算法保护应用数据。
- 数字签名:发送方用私钥生成签名,接收方用公钥按相应算法验证。把所有签名都描述为“私钥加密哈希、公钥解密”只适合非常粗略地类比部分 RSA 机制,不适用于 ECDSA 等算法。
- 数字证书:CA 用私钥签名"服务器公钥 + 域名 + 有效期",浏览器用 CA 的公钥验证。