4. 常见哈希算法(二):SHA-1 算法原理、结构与对比
SHA-1(Secure Hash Algorithm 1)由美国国家标准与技术研究院(NIST)于 1995 年发布,是 SHA-0 的改进版本。它在很长一段时间内被广泛应用于 TLS、SSL、PGP、SSH、Git 等协议中。然而,随着密码分析技术的发展,SHA-1 已被证明存在严重的安全弱点,目前已被业界逐步淘汰。
4.1 SHA-1 算法核心参数
| 参数项 | SHA-1 值 |
|---|---|
| 消息摘要长度 | 160 比特(20 字节) |
| 分组处理长度 | 512 比特(64 字节) |
| 字长 | 32 比特 |
| 最大输入长度 | 264 − 1 比特 |
| 压缩轮数 | 80 轮 |
| 初始链接变量 | 5 个 32 位寄存器(A, B, C, D, E) |
4.2 SHA-1 算法结构
SHA-1 采用 Merkle-Damgård 迭代结构,处理流程分为三个主要阶段:消息填充与长度编码、分组扩展、80 轮压缩函数迭代。
关键步骤: 消息先填充至 512 比特的整数倍,最后 64 比特存放原始消息长度(大端序)。每个 512 比特分组被扩展为 80 个 32 比特字,然后通过 80 轮迭代更新 5 个链接变量。
4.3 80 轮压缩函数详解
SHA-1 的压缩函数对每个 512 比特分组执行 80 轮迭代,每轮使用一个不同的常数 Kt 和逻辑函数 ft。80 轮分为 4 个阶段,每 20 轮使用相同的逻辑函数和常数。
| 轮次范围 | 逻辑函数 ft(B, C, D) | 常数 Kt(十六进制) |
|---|---|---|
| 0 – 19 | (B ∧ C) ∨ (¬B ∧ D) | 0x5A827999 |
| 20 – 39 | B ⊕ C ⊕ D | 0x6ED9EBA1 |
| 40 – 59 | (B ∧ C) ∨ (B ∧ D) ∨ (C ∧ D) | 0x8F1BBCDC |
| 60 – 79 | B ⊕ C ⊕ D | 0xCA62C1D6 |
轮函数说明: 第 20–39 轮和第 60–79 轮使用相同的异或函数,但常数不同。第 40–59 轮使用多数函数(Majority),具有较好的雪崩效应。
4.4 单轮迭代运算
每轮迭代更新 5 个 32 位寄存器(A, B, C, D, E)。单轮运算公式如下:
TEMP = (A <<< 5) + f_t(B, C, D) + E + W_t + K_t
E = D
D = C
C = B <<< 30
B = A
A = TEMP
其中 Wt 是扩展后的消息字,由原始 512 比特分组通过以下方式生成:
W_t = M_t (0 ≤ t ≤ 15)
W_t = (W_{t-3} ⊕ W_{t-8} ⊕ W_{t-14} ⊕ W_{t-16}) <<< 1 (16 ≤ t ≤ 79)
4.5 SHA-1 与 MD5 的对比
SHA-1 和 MD5 都基于 Merkle-Damgård 结构,但 SHA-1 在安全性设计上更为保守。下表从多个维度进行对比:
| 对比维度 | MD5 | SHA-1 |
|---|---|---|
| 摘要长度 | 128 比特 | 160 比特 |
| 轮数 | 64 轮(4 轮 × 16 步) | 80 轮(4 轮 × 20 步) |
| 字长 | 32 比特 | 32 比特 |
| 分组大小 | 512 比特 | 512 比特 |
| 逻辑函数数量 | 4 个(每轮不同) | 3 个(第 20–39 与 60–79 轮相同) |
| 循环左移量 | 每步不同(4 种) | 固定(A 左移 5,B 左移 30) |
| 加法常数 | 64 个(每步不同) | 4 个(每 20 轮相同) |
| 抗碰撞强度(理论) | 264 次操作 | 280 次操作 |
| 已知最佳碰撞攻击 | 218 次操作(2009) | 257.5 次操作(2020) |
| 当前安全状态 | 已破解,不推荐使用 | 已破解,不推荐使用 |
安全警示: 无论是 MD5 还是 SHA-1,目前都已不再满足抗碰撞安全性要求。任何需要抵抗碰撞攻击的场景(如数字签名、证书签发)都应使用 SHA-256 或更高强度的哈希算法。
4.6 已知碰撞攻击
SHA-1 的碰撞攻击经历了多年的演进,以下为关键里程碑:
- 2005 年:王小云团队提出首个理论攻击,复杂度约 269 次操作。
- 2015 年:Marc Stevens 团队将攻击复杂度降至 257.5 次操作,并发布 SHAttered 攻击,生成两个不同 PDF 文件具有相同 SHA-1 哈希值。
- 2017 年:Google 与 CWI 研究所合作,实际演示 SHAttered 攻击,仅需约 6500 CPU 年(或 110 GPU 年)即可找到碰撞。
- 2020 年:SHAttered 攻击被进一步优化,成本降至约 45,000 美元。
SHAttered 攻击要点: 攻击者利用 SHA-1 压缩函数中的局部碰撞和差分路径,通过选择前缀碰撞技术,在保持两个消息前缀相同的情况下,使后续分组产生相同的摘要值。该攻击不依赖于消息长度,可应用于 PDF、证书等任意格式。
4.7 迁移建议
鉴于 SHA-1 已被实际碰撞攻击证明不安全,业界已全面推动迁移:
- 数字证书:主流 CA 自 2017 年起停止签发 SHA-1 证书,浏览器对 SHA-1 证书显示安全警告。
- 代码签名:Windows、macOS 等操作系统已拒绝 SHA-1 签名的驱动程序或可执行文件。
- 版本控制:Git 虽然仍使用 SHA-1 作为对象标识符,但已开始过渡到 SHA-256(通过 Git 2.29+ 的扩展哈希支持)。
- HMAC:HMAC-SHA-1 在密钥未知的情况下仍被认为安全,但建议新系统使用 HMAC-SHA-256。
兼容性处理: 对于遗留系统中必须验证 SHA-1 签名的场景,建议采用双重签名策略(同时提供 SHA-1 和 SHA-256 签名),并在验证时优先使用 SHA-256。