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 个链接变量。
SHA-1 整体处理流程(Merkle-Damgård 结构) 输入消息 M 填充 + 长度编码 分组 1 (512 bit) 分组 2 (512 bit) 分组 n (512 bit) 初始 IV (160 bit) 压缩函数 f (80 轮迭代) 中间链接变量 160 bit 消息摘要

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)
SHA-1 单轮迭代结构(第 t 轮) A B C D E f_t(B, C, D) 逻辑函数 K_t 常数 W_t 扩展字 模 2³² 加法器 A <<< 5 A' B' C' D' E' B <<< 30

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 已被实际碰撞攻击证明不安全,业界已全面推动迁移:

  1. 数字证书:主流 CA 自 2017 年起停止签发 SHA-1 证书,浏览器对 SHA-1 证书显示安全警告。
  2. 代码签名:Windows、macOS 等操作系统已拒绝 SHA-1 签名的驱动程序或可执行文件。
  3. 版本控制:Git 虽然仍使用 SHA-1 作为对象标识符,但已开始过渡到 SHA-256(通过 Git 2.29+ 的扩展哈希支持)。
  4. HMAC:HMAC-SHA-1 在密钥未知的情况下仍被认为安全,但建议新系统使用 HMAC-SHA-256。
兼容性处理: 对于遗留系统中必须验证 SHA-1 签名的场景,建议采用双重签名策略(同时提供 SHA-1 和 SHA-256 签名),并在验证时优先使用 SHA-256。