security hash sha2 sha3 cryptography

SHA-2 与 SHA-3 哈希家族全攻略

深入分析并比较 SHA-2 与 SHA-3 哈希变体,包括 SHAKE 和 BLAKE2 的技术细节。

现代哈希技术简介

加密哈希函数是数字安全的幕后英雄。从保护密码到验证数 GB 软件分发的完整性,它们为数据提供了“数字指纹”。随着计算能力的增强和密码分析技术的发展,行业已经从 MD5 和 SHA-1 等旧算法转向更强大的标准:SHA-2 和更新的 SHA-3。

在本指南中,我们将深入探讨 SHA-2 和 SHA-3 家族的复杂性,比较它们的底层架构,并了解 BLAKE2 等现代替代方案。我们还将深入研究使这些算法安全的代码基础,并讨论为什么转向 SHA-3 代表了密码学史上的一个重要里程碑。


SHA-2 家族:互联网的中流砥柱

SHA-2(安全哈希算法 2)由美国国家安全局 (NSA) 开发并于 2001 年由 NIST 发布,取代了存在漏洞的 SHA-1。SHA-2 基于 Merkle-Damgård 结构,这是一种从单向压缩函数构建抗碰撞哈希函数的方法。

SHA-2 的变体

SHA-2 家族包含六个具有不同摘要大小的哈希函数:

  1. SHA-256:使用最广泛的变体。它生成 256 位(32 字节)的哈希值。它是比特币和许多 SSL/TLS 证书的核心。它在 32 位字上运行,并使用 512 位的块大小。
  2. SHA-512:专为 64 位处理器设计,生成 512 位(64 字节)的哈希值。在 64 位硬件上通常比 SHA-256 快,因为它在 64 位字上运行,并使用更大的 1024 位块大小。
  3. SHA-224:SHA-256 的截断版本,使用不同的初始值 (IV)。
  4. SHA-384:SHA-512 的截断版本,具有独特的 IV。
  5. SHA-512/224 和 SHA-512/256:这些是 SHA-512 的截断版本,比 SHA-256 更能抵抗“长度扩展攻击”,同时在 64 位系统上保持高性能。

Merkle-Damgård 结构详解

Merkle-Damgård 结构的工作原理如下:

  1. 填充 (Padding):对消息进行填充,使其长度为固定块大小(例如 SHA-256 为 512 位)的倍数。填充包括原始消息长度,这对于安全性证明至关重要。
  2. 迭代处理:消息被分解为多个块 $M_1, M_2, \dots, M_n$。
  3. 压缩函数:按顺序处理每个块。$H_i = f(H_{i-1}, M_i)$,其中 $f$ 是单向压缩函数,$H_0$ 是初始值 (IV)。

深度研究:压缩函数 在 SHA-256 中,压缩函数使用 64 轮操作,结合了逻辑函数(AND, OR, XOR, NOT)、位循环移位和偏移。它还使用了源自前 64 个质数的 64 个常量,这确保了映射是非线性的,并且能够抵御线性密码分析。

长度扩展攻击 (Length Extension Attack) 漏洞

Merkle-Damgård 结构的一个固有弱点是长度扩展攻击。如果攻击者知道 Hash(Message)Message 的长度,即使不知道原始消息,也可以计算出 Hash(Message || Padding || Extension)。这是因为 Merkle-Damgård 哈希的输出正是处理完最后一个块后算法的内部状态。通过将该输出作为新的起始状态,攻击者可以简单地使用新数据“继续”哈希过程。


SHA-3 家族:范式转移

虽然 SHA-2 目前仍然安全,但 NIST 在 2007 年发起了一场竞赛,旨在寻找一种完全不同的算法作为备份。获胜者是 Keccak,它在 2015 年成为了 SHA-3 标准。

海绵结构 (Sponge Construction):吸收与挤出

与 SHA-2 不同,SHA-3 使用海绵结构。该架构涉及一个 1600 位的内部状态,组织为 64 位通道的 5x5 数组。海绵结构有两个主要参数:

  • 速率 (Rate, r):每次迭代中处理的位数。
  • 容量 (Capacity, c):永远不会被消息数据直接接触的内部状态位,提供安全缓冲。$r + c = 1600$。

该过程涉及两个阶段:

  1. 吸收 (Absorbing):消息块被异或 (XOR) 到状态的前 $r$ 位中,然后执行置换函数 $P$,打乱整个 1600 位状态。
  2. 挤出 (Squeezing):一旦整个消息被吸收,就从状态的前 $r$ 位读取位作为输出。如果需要更多位,则再次应用置换 $P$。

为什么海绵结构更优越

由于内部状态 (1600 位) 远大于输出哈希值 (例如 256 或 512 位),并且由于保持隐藏的“容量”位,SHA-3 天然具有抗长度扩展攻击的能力。你无法“继续”哈希,因为你不知道隐藏的容量位。

SHA-3 的变体

为了兼容性,SHA-3 镜像了 SHA-2 的输出大小:

  • SHA-3-224 ($c=448$)
  • SHA-3-256 ($c=512$)
  • SHA-3-384 ($c=768$)
  • SHA-3-512 ($c=1024$)

SHAKE:可变输出函数 (XOF)

SHA-3 标准最创新的功能之一是引入了 SHAKE (Secure Hash Algorithm and Keccak)。与产生固定长度输出的传统哈希函数不同,SHAKE128 和 SHAKE256 允许你指定任意输出长度。

  • SHAKE128:只要输出足够长,就能针对所有攻击(原像、第二原像和碰撞)提供 128 位安全性。
  • SHAKE256:提供 256 位安全性。

SHAKE 的实际应用场景:

  1. 全域哈希 (Full Domain Hashing, FDH):将任意字符串映射到群的元素(常见于 RSA-PSS 签名)。
  2. 掩码生成函数 (MGF):在非对称加密中用于填充消息。
  3. 伪随机数生成:从一个小的种子生成大量看似随机的数据流。

BLAKE2:高性能替代方案

虽然不是 NIST 标准,但 BLAKE2(基于 SHA-3 竞赛中的 BLAKE 算法)因其极高的速度在行业中备受推崇。

  • BLAKE2b:针对 64 位平台进行了优化。它可以产生高达 512 位的摘要。
  • BLAKE2s:针对 8 位到 32 位平台进行了优化。它可以产生高达 256 位的摘要。

为什么要使用 BLAKE2? 在大多数现代 CPU 上,它的速度明显快于 SHA-3,甚至通常快于 SHA-2。它包含对带密钥哈希 (MAC)、盐和个性化的内置支持,使其成为开发者的多功能工具。它是 WireGuard 和 Argon2 中的默认哈希算法。


对比表:SHA-2 vs. SHA-3 vs. BLAKE2

特性 SHA-2 (SHA-256) SHA-3 (SHA-3-256) BLAKE2 (BLAKE2b)
结构 Merkle-Damgård 海绵结构 改进的 HAIFA
速度 中等 较慢(软件实现) 极快
硬件支持 广泛(Intel SHA 扩展) 增长中 优秀
长度扩展攻击 存在漏洞 免疫 免疫
标准化机构 NIST (2001) NIST (2015) RFC 7693
主要应用场景 Web 安全 (SSL/TLS) 面向未来的系统 高速数据完整性校验

安全性分析:为什么要转向 SHA-3?

1. 密码学多样性

如果密码分析取得突破并破解了 Merkle-Damgård 结构,所有的 SHA-2 变体都会失效。SHA-3(海绵结构)提供了完全不同的数学基础,作为全球安全基础设施的“备选方案”。

2. 抗 Grover 算法(量子计算)能力

量子计算机可以使用 Grover 算法在 $2^{n/2}$ 时间内找到原像。虽然这使所有哈希函数的有效安全性减半,但 SHA-3 更大的内部状态和结构通常被认为在后量子时代更具鲁棒性。

3. 构造上的安全性

许多开发者使用 Hash(Key || Message) 作为简单的 MAC。对于 SHA-2,由于长度扩展攻击,这是不安全的。对于 SHA-3,这种构造实际上是安全的(尽管为了符合标准,仍建议使用 HMAC 或 KMAC)。


代码示例

Node.js(使用 crypto 模块)

const crypto = require('crypto');

const data = 'The quick brown fox jumps over the lazy dog';

// SHA-256 (SHA-2)
const sha256 = crypto.createHash('sha256').update(data).digest('hex');
console.log(`SHA-256: ${sha256}`);

// SHA3-256 (SHA-3)
const sha3 = crypto.createHash('sha3-256').update(data).digest('hex');
console.log(`SHA3-256: ${sha3}`);

// SHAKE256,输出 64 字节(512 位)
const shake = crypto.createHash('shake256', { outputLength: 64 })
                    .update(data)
                    .digest('hex');
console.log(`SHAKE256: ${shake}`);

Python(使用 hashlib

import hashlib

data = b'The quick brown fox jumps over the lazy dog'

# SHA-256
print(f"SHA-256: {hashlib.sha256(data).hexdigest()}")

# SHA3-256
print(f"SHA3-256: {hashlib.sha3_256(data).hexdigest()}")

# SHAKE256
s = hashlib.shake_256(data)
print(f"SHAKE256 (32 字节): {s.hexdigest(32)}")

FAQ:常见误解

1. SHA-3 比 SHA-2 “更安全”吗?

目前两者都被认为能够抵御所有已知的实际攻击。SHA-3 在设计上“更安全”,因为它避免了长度扩展漏洞,但 SHA-256 并未“失效”,对于大多数应用来说仍然非常可靠。

2. 为什么 SHA-3 的软件实现较慢?

Keccak 在设计时考虑了硬件效率。虽然它在 FPGA 和 ASIC 上极快,但对于通用 CPU 来说,其位交织和置换操作比以算术运算为主的 SHA-2 略显复杂。

3. 我应该对所有任务都使用 SHA-512 吗?

在 64 位机器上,SHA-512 通常比 SHA-256 快,并提供更高的安全余量。然而,它生成的摘要非常长,对于文件校验和等简单任务来说可能有些大材小用。

4. SHAKE 和 SHA-3 有什么区别?

SHA-3 具有固定的输出长度。SHAKE 是一种 XOF(可变输出函数),它使用相同的 Keccak 引擎,但允许你请求任意数量的位,本质上就像一个可以无限挤出的海绵。


结论

选择合适的哈希函数取决于你的具体需求。对于通用性和行业兼容性,SHA-256 仍然是标准。如果你正在构建一个新系统,并希望获得最高的架构安全性以及抗长度扩展攻击能力,SHA-3 是更优的选择。对于对速度要求极高的应用,BLAKE2 是一个强大且备受推崇的替代方案。