抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

HTTPS(HTTP Secure)是 HTTP 协议的安全版本,通过 TLS(Transport Layer Security)协议对通信进行加密。本文将详细介绍 HTTPS 的握手过程、涉及的加密算法,以及为什么这种设计能保证通信安全。

一、HTTPS 概述

1.1 为什么需要 HTTPS

HTTP 协议是明文传输的,存在三大安全风险:

风险 说明 攻击示例
窃听 第三方可以截获通信内容 在公共 WiFi 抓包获取密码
篡改 第三方可以修改通信内容 运营商注入广告
冒充 无法验证通信方身份 钓鱼网站伪装成银行

HTTPS 通过 TLS 协议解决了这三个问题:

  • 加密:防止窃听
  • 完整性校验:防止篡改
  • 身份认证:防止冒充

1.2 HTTPS 协议栈

1
2
3
4
5
6
7
8
9
+------------------+
| HTTP | <- 应用层协议
+------------------+
| TLS | <- 安全层(加密、认证)
+------------------+
| TCP | <- 传输层
+------------------+
| IP | <- 网络层
+------------------+

二、加密算法基础

在理解握手过程之前,需要先了解涉及的加密算法。

2.1 对称加密

特点:加密和解密使用同一个密钥,速度快。

1
2
明文 + 密钥 -> 加密算法 -> 密文
密文 + 密钥 -> 解密算法 -> 明文

常用算法

算法 密钥长度 说明
AES-128 128 bits 目前最常用,安全高效
AES-256 256 bits 更高安全级别
ChaCha20 256 bits 移动设备友好,速度快

问题:如何安全地将密钥传递给对方?

2.2 非对称加密

特点:使用一对密钥(公钥和私钥),公钥加密的数据只有私钥能解密。

1
2
明文 + 公钥 -> 加密算法 -> 密文
密文 + 私钥 -> 解密算法 -> 明文

常用算法

算法 说明
RSA 基于大整数分解难题,经典算法
ECDHE 基于椭圆曲线,密钥更短,性能更好

特点

  • 公钥可以公开,私钥必须保密
  • 计算复杂度高,速度比对称加密慢 100-1000 倍
  • 主要用于密钥交换和数字签名

2.3 密钥交换算法

用于在不安全的信道上协商出一个共享密钥。

Diffie-Hellman(DH)密钥交换

1
2
3
4
5
6
7
8
9
10
11
        Alice                          Bob
| |
私钥 a | | 私钥 b
公钥 A=g^a mod p | 公钥 B=g^b mod p
| |
|<-------- 交换公钥 A, B ------>|
| |
计算 K=B^a mod p | 计算 K=A^b mod p
=g^(ab) mod p | =g^(ab) mod p
| |
| 双方得到相同的 K |

安全性:即使攻击者截获了 A 和 B,也无法计算出 K(离散对数难题)。

ECDHE(椭圆曲线 DH)

基于椭圆曲线的 DH 算法,相同安全级别下密钥更短:

安全级别 RSA 密钥长度 ECC 密钥长度
128 bits 3072 bits 256 bits
256 bits 15360 bits 512 bits

2.4 数字签名

用于验证数据完整性和发送者身份。

1
2
3
4
5
6
7
签名过程:
数据 -> Hash -> 摘要 -> 私钥加密 -> 签名

验证过程:
签名 -> 公钥解密 -> 摘要1
数据 -> Hash -> 摘要2
比较摘要1和摘要2是否相同

常用算法:RSA-SHA256、ECDSA

2.5 哈希算法

将任意长度数据映射为固定长度摘要,单向不可逆。

算法 输出长度 说明
SHA-256 256 bits 目前最常用
SHA-384 384 bits 更高安全级别

三、TLS 1.2 握手过程

3.1 握手流程概览

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
客户端                                          服务器
| |
| 1. ClientHello |
|---------------------------------------------->|
| |
| 2. ServerHello |
|<----------------------------------------------|
| 3. Certificate |
|<----------------------------------------------|
| 4. ServerKeyExchange (ECDHE) |
|<----------------------------------------------|
| 5. ServerHelloDone |
|<----------------------------------------------|
| |
| 6. ClientKeyExchange |
|---------------------------------------------->|
| 7. ChangeCipherSpec |
|---------------------------------------------->|
| 8. Finished (加密) |
|---------------------------------------------->|
| |
| 9. ChangeCipherSpec |
|<----------------------------------------------|
| 10. Finished (加密) |
|<----------------------------------------------|
| |
| ========== 加密通信开始 ========== |
|<=============================================>|

3.2 详细过程

第一步:ClientHello

客户端发起握手,发送以下信息:

1
2
3
4
5
6
7
8
9
10
ClientHello:
- 支持的 TLS 版本: TLS 1.2
- 客户端随机数: Random_C (32 字节)
- 支持的加密套件列表:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_GCM_SHA256
...
- 支持的压缩方法
- 扩展字段 (SNI, ALPN 等)

加密套件命名规则

1
2
3
4
5
6
7
8
9
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
^ ^ ^ ^ ^ ^
| | | | | |
| | | | | +-- MAC 算法
| | | | +------- 分组模式
| | | +----------- 密钥长度
| | +---------------- 对称加密算法
| +------------------------- 身份认证算法
+-------------------------------- 密钥交换算法

第二步:ServerHello

服务器响应,确认使用的参数:

1
2
3
4
5
6
ServerHello:
- 选定的 TLS 版本: TLS 1.2
- 服务器随机数: Random_S (32 字节)
- 选定的加密套件: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- 选定的压缩方法
- Session ID (用于会话恢复)

第三步:Certificate

服务器发送证书链:

1
2
3
4
Certificate:
- 服务器证书 (包含服务器公钥)
- 中间 CA 证书
- (根 CA 证书通常不发送,客户端本地有)

证书包含:

  • 服务器域名
  • 服务器公钥
  • 证书有效期
  • 颁发机构(CA)
  • CA 的数字签名

第四步:ServerKeyExchange

服务器发送 ECDHE 密钥交换参数:

1
2
3
4
ServerKeyExchange:
- 椭圆曲线类型: secp256r1
- 服务器 ECDHE 公钥: Server_ECDHE_Pub
- 签名: RSA_Sign(Random_C + Random_S + 曲线参数 + 公钥)

签名的作用:证明这些参数确实来自证书对应的服务器,防止中间人攻击。

第五步:ServerHelloDone

服务器表示 Hello 阶段结束。

第六步:ClientKeyExchange

客户端发送自己的 ECDHE 公钥:

1
2
ClientKeyExchange:
- 客户端 ECDHE 公钥: Client_ECDHE_Pub

此时双方都可以计算出 预主密钥(Pre-Master Secret)

1
2
Pre_Master_Secret = ECDH(Client_ECDHE_Priv, Server_ECDHE_Pub)
= ECDH(Server_ECDHE_Priv, Client_ECDHE_Pub)

第七步:生成主密钥

双方使用 PRF(伪随机函数)生成主密钥:

1
2
3
Master_Secret = PRF(Pre_Master_Secret,
"master secret",
Random_C + Random_S)

然后从主密钥派生出多个密钥:

1
2
3
4
5
6
7
8
9
10
11
Key_Block = PRF(Master_Secret,
"key expansion",
Random_S + Random_C)

从 Key_Block 中提取:
- client_write_MAC_key (MAC 密钥)
- server_write_MAC_key
- client_write_key (对称加密密钥)
- server_write_key
- client_write_IV (初始化向量)
- server_write_IV

第八步:ChangeCipherSpec + Finished

客户端发送 ChangeCipherSpec 表示后续消息将使用加密。

然后发送 Finished 消息(第一条加密消息):

1
2
3
4
Finished:
- verify_data = PRF(Master_Secret,
"client finished",
Hash(所有握手消息))

第九、十步:服务器响应

服务器同样发送 ChangeCipherSpecFinished

双方验证对方的 Finished 消息正确后,握手完成。

3.3 完整流程图

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
29
30
31
32
33
34
35
36
37
38
39
40
客户端                                                服务器
| |
| ClientHello (版本, Random_C, 加密套件列表) |
|---------------------------------------------------->|
| |
| ServerHello (版本, Random_S, 选定的加密套件) |
|<----------------------------------------------------|
| Certificate (服务器证书链) |
|<----------------------------------------------------|
| ServerKeyExchange (ECDHE 公钥 + 签名) |
|<----------------------------------------------------|
| ServerHelloDone |
|<----------------------------------------------------|
| |
| [验证证书] |
| [验证签名] |
| |
| ClientKeyExchange (客户端 ECDHE 公钥) |
|---------------------------------------------------->|
| |
| [计算 Pre-Master Secret] [计算 Pre-Master Secret]
| [派生 Master Secret] [派生 Master Secret]
| [生成对称密钥] [生成对称密钥]
| |
| ChangeCipherSpec |
|---------------------------------------------------->|
| Finished (加密验证数据) |
|---------------------------------------------------->|
| |
| [验证 Finished] |
| |
| ChangeCipherSpec |
|<----------------------------------------------------|
| Finished (加密验证数据) |
|<----------------------------------------------------|
| |
| [验证 Finished] |
| |
| ============= HTTPS 加密通信 ============= |
|<===================================================>|

四、TLS 1.3 握手改进

TLS 1.3 大幅简化了握手过程,只需要 1-RTT(往返时间)。

4.1 TLS 1.3 握手流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
客户端                                          服务器
| |
| ClientHello + KeyShare |
|---------------------------------------------->|
| |
| ServerHello + KeyShare |
|<----------------------------------------------|
| {EncryptedExtensions} |
|<----------------------------------------------|
| {Certificate} |
|<----------------------------------------------|
| {CertificateVerify} |
|<----------------------------------------------|
| {Finished} |
|<----------------------------------------------|
| |
| {Finished} |
|---------------------------------------------->|
| |
| ========== 加密通信 ========== |
|<=============================================>|

{} 表示加密的消息

4.2 主要改进

特性 TLS 1.2 TLS 1.3
握手 RTT 2-RTT 1-RTT
0-RTT 恢复 不支持 支持
加密套件 37+ 种 5 种
密钥交换 RSA/DH/ECDHE 仅 ECDHE
对称加密 多种模式 仅 AEAD
握手加密 明文 部分加密

4.3 0-RTT 模式

对于恢复的会话,TLS 1.3 支持 0-RTT:

1
2
3
4
5
客户端                                          服务器
| |
| ClientHello + KeyShare + EarlyData (加密) |
|---------------------------------------------->|
| |

客户端可以在第一个消息中就发送加密的应用数据。

五、安全性分析

5.1 为什么使用两种加密?

加密类型 优点 缺点 用途
非对称加密 无需预共享密钥 速度慢 密钥交换、身份认证
对称加密 速度快 需要共享密钥 数据加密

HTTPS 结合两者优点:

  1. 用非对称加密交换对称密钥(安全)
  2. 用对称加密传输数据(高效)

5.2 防止窃听

1
2
3
4
5
6
7
8
9
10
攻击者截获的信息:
- Random_C, Random_S (公开的随机数)
- 服务器证书 (公开)
- ECDHE 公钥 (公开)

攻击者无法获得:
- ECDHE 私钥 (从未传输)
- Pre-Master Secret (需要私钥计算)
- Master Secret (需要 Pre-Master Secret)
- 对称加密密钥 (需要 Master Secret)

ECDHE 的前向安全性

即使服务器私钥泄露,攻击者也无法解密过去的通信:

  • 每次连接使用临时的 ECDHE 密钥对
  • 会话结束后临时私钥被销毁
  • 服务器私钥只用于签名,不用于加密

5.3 防止篡改

握手阶段

  • Finished 消息包含所有握手消息的哈希
  • 任何篡改都会导致哈希不匹配,握手失败

数据传输阶段

  • 使用 AEAD(认证加密)算法,如 AES-GCM
  • 每条消息都有认证标签(MAC)
  • 篡改数据会导致 MAC 验证失败
1
2
3
4
5
6
7
AEAD 加密:
密文 = Encrypt(密钥, 明文, 附加数据)
输出: 密文 + 认证标签 (16 字节)

AEAD 解密:
先验证认证标签
标签正确才解密,否则拒绝

5.4 防止冒充(证书验证)

客户端验证服务器身份的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. 检查证书链
服务器证书 <- 中间 CA 签名 <- 根 CA 签名
^
|
本地信任的根 CA

2. 验证证书有效性
- 域名匹配
- 有效期
- 未被吊销 (OCSP/CRL)

3. 验证服务器拥有私钥
ServerKeyExchange 中的签名
只有持有私钥才能生成正确签名

5.5 防止中间人攻击

中间人攻击尝试:

1
客户端 <-----> 攻击者 <-----> 服务器

攻击者无法成功,因为:

  1. 无法伪造证书:没有 CA 的私钥,无法签发有效证书
  2. 无法伪造签名:没有服务器私钥,无法签名 KeyExchange
  3. 证书域名不匹配:客户端会检测到

5.6 随机数的作用

随机数 作用
Random_C 防止重放攻击,增加密钥随机性
Random_S 防止重放攻击,增加密钥随机性
ECDHE 私钥 临时生成,提供前向安全性

为什么需要两个随机数?

  • 即使攻击者控制了其中一个,密钥仍然是随机的
  • 防止服务器或客户端单方面控制密钥

六、抓包分析

使用 Wireshark 抓取 TLS 1.2 握手:

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
29
30
31
32
33
34
35
1. ClientHello
Version: TLS 1.2
Random: 5f8c3a... (32 bytes)
Cipher Suites (17 suites):
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
...

2. ServerHello
Version: TLS 1.2
Random: 7b2e4f... (32 bytes)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

3. Certificate
Certificates (2 entries):
- example.com (server cert)
- Let's Encrypt R3 (intermediate)

4. Server Key Exchange
EC Diffie-Hellman:
Curve Type: named_curve (secp256r1)
Public Key: 04a3b2c1... (65 bytes)
Signature: 3045022100...

5. Client Key Exchange
EC Diffie-Hellman:
Public Key: 04d5e6f7... (65 bytes)

6. Change Cipher Spec
7. Encrypted Handshake Message (Finished)

8. Change Cipher Spec
9. Encrypted Handshake Message (Finished)

10. Application Data (encrypted)

七、常见加密套件

7.1 推荐的加密套件

1
2
3
4
5
6
7
8
9
10
11
12
# TLS 1.3 (只有 5 种)
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.2 推荐
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256

7.2 应该禁用的加密套件

1
2
3
4
5
6
7
# 不安全,应禁用
TLS_RSA_WITH_* (无前向安全性)
*_WITH_RC4_* (RC4 已被破解)
*_WITH_3DES_* (Sweet32 攻击)
*_WITH_*_CBC_* (BEAST/Lucky13 攻击)
*_EXPORT_* (弱密钥)
*_NULL_* (无加密)

八、总结

8.1 HTTPS 安全机制

安全目标 实现方式
机密性 AES/ChaCha20 对称加密
完整性 HMAC/AEAD 认证
身份认证 数字证书 + 签名
前向安全 ECDHE 临时密钥
防重放 随机数 + 序列号

8.2 为什么这样设计是安全的

  1. 密钥协商:ECDHE 保证即使被窃听也无法得到密钥
  2. 前向安全:临时密钥保证历史通信的安全
  3. 身份验证:证书链保证服务器身份可信
  4. 完整性保护:AEAD 保证数据不被篡改
  5. 分层防御:即使某一层被攻破,其他层仍有保护

8.3 一图总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────┐
│ HTTPS 安全体系 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 身份认证 │ │ 密钥协商 │ │ 数据加密 │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ X.509 证书 │ │ ECDHE │ │ AES-GCM │ │
│ │ RSA/ECDSA │ │ 前向安全 │ │ ChaCha20 │ │
│ │ 签名 │ │ 临时密钥 │ │ AEAD │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ v v v │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 防窃听 + 防篡改 + 防冒充 │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘

参考资料