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(所有握手消息))
第九、十步:服务器响应 服务器同样发送 ChangeCipherSpec 和 Finished。
双方验证对方的 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 结合两者优点:
用非对称加密交换对称密钥(安全)
用对称加密传输数据(高效)
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 客户端 <-----> 攻击者 <-----> 服务器
攻击者无法成功,因为:
无法伪造证书 :没有 CA 的私钥,无法签发有效证书
无法伪造签名 :没有服务器私钥,无法签名 KeyExchange
证书域名不匹配 :客户端会检测到
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 为什么这样设计是安全的
密钥协商 :ECDHE 保证即使被窃听也无法得到密钥
前向安全 :临时密钥保证历史通信的安全
身份验证 :证书链保证服务器身份可信
完整性保护 :AEAD 保证数据不被篡改
分层防御 :即使某一层被攻破,其他层仍有保护
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 │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 防窃听 + 防篡改 + 防冒充 │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘
参考资料