哈希函数:SHA-3 与 BLAKE3 设计原理
密码学哈希函数是数字世界的指纹仪:任意长输入映射为定长输出,改动输入一个比特,输出应约半数比特翻转(雪崩效应);给定输出反推输入不可行(抗原像);找到两个不同输入得到同一输出不可行(抗碰撞)。MD5 与 SHA-1 的相继破解告诉我们,这些性质不是靠『看起来乱』获得的,而是由内部结构严格保证的。本文对比两代设计范式:SHA-3 的海绵结构(sponge construction)与 BLAKE3 基于 BLAKE2s 血统的 ARX 压缩函数加树形哈希,再用一段可运行实验把海绵行为、雪崩指标与著名的长度扩展攻击一次性跑给您看。
一、SHA-3 的海绵结构:吸收与挤压
SHA-3(Keccak,NIST 2015 标准化)彻底抛弃了 SHA-2 时代的 Merkle-Damgård 结构,改用海绵结构。状态是一个 1600 位的方阵,分为两部分:
- 速率 r(rate):与外部交换数据的部分,输入块逐块异或进来、输出从这部分读出;
- 容量 c(capacity):永不暴露给外部的内部秘密部分,安全强度直接由 c 决定(c 越大越安全,r 越小越慢)。
工作分两阶段:吸收(absorb)——每块输入异或进速率部分后整体过一轮置换 f;挤压(squeeze)——从速率部分读出输出,需要更多输出就再过一轮置换继续读。由于输出只暴露速率部分、容量部分全程隐藏,海绵结构天然免疫长度扩展攻击(下文实验直接演示)。它还有一个天然红利:XOF(可扩展输出函数),SHAKE128/SHAKE256 想输出多长就挤压多长。
二、BLAKE3:ARX 压缩函数与树形并行
BLAKE3(2020)的设计目标与 SHA-3 不同:不追求 NIST 标准化的保守,而是把性能与并行度拉满。核心特征:
- ARX 压缩函数:只用加(Add)、轮(Rotate)、异或(XOR)三种运算——现代 CPU 上全是单周期指令,无需查表,天然抗时序侧信道;
- 树形哈希:输入按 1KB 分块独立压缩成子树,再两两归并成根。任意子树可并行计算,大文件哈希可以线性加速——这是 MD 结构与海绵结构都做不到的(它们本质串行);
- 一个原语打天下:同一压缩函数同时充当哈希、XOF、KDF、MAC、PRNG,工程上大幅简化依赖与审计面。
BLAKE3 与 BLAKE2s 共享压缩函数血统,因此雪崩特性同级——下文实验用标准库里的 BLAKE2s 代替测量(BLAKE3 不在 Python 标准库中)。
三、长度扩展攻击:MD 结构的阿喀琉斯之踵
Merkle-Damgård 结构(MD5/SHA-1/SHA-2 的共同骨架)逐块压缩,最终输出就是完整的内部状态。这带来一个经典漏洞:攻击者截获 H(secret||msg) 后,不需要知道 secret,就可以把截获的哈希值当作中间状态继续压缩追加数据,伪造出合法的 H(secret||msg||glue||ext)。这正是早期 Flickr 等 API 用『密钥拼接消息』做签名被攻破的原理,也是 HMAC 存在的原因。海绵结构因容量部分不可见而结构性免疫。
四、动手实验:三种性质一次跑通
实验在您的服务器上以 Python 3 直接运行,覆盖三部分:教学版海绵结构(64 位状态、16 位速率 + 48 位容量、ARX 多轮置换)的吸收/挤压与雪崩演示;用标准库实测 SHA-256、SHA-3-256、BLAKE2s 的雪崩指标(200 次单比特翻转取平均);用同一套压缩函数分别搭建 MD 结构与海绵结构,演示长度扩展攻击在前者成功、在后者失败。核心片段:
# 教学海绵: 输入异或进速率部分 -> 置换; 输出只取速率部分
def absorb(self, data):
for i in range(0, len(data), 2): # 速率 16bit
blk = int.from_bytes(data[i:i+2].ljust(2, b'\x00'), 'big')
self.state ^= blk << 48 # 只注入高 16 位
self._f() # 24 轮 ARX 置换
# 雪崩实测: 先取基线哈希, 再翻转 1 比特后对比
h1 = fn(orig).digest()
mut = bytearray(orig); mut[i % 32] ^= 1 << (i % 8)
h2 = fn(bytes(mut)).digest()
flips = bin(int(h1) ^ int(h2)).count('1')
# 长度扩展: MD 用截获状态续算; 海绵容量不可见故无法伪造
forged = ToyMD(state=intercept); forged.update(ext)
real = ToyMD(); real.update(secret + msg + glue + ext)
assert forged.state == real.state # MD: 攻击成功
atk.state = int.from_bytes(digest[-2:], 'big') << 48 # 海绵: 重建失败
assert atk.squeeze(8) != real_sponge.squeeze(8)
真实运行输出:
== 海绵结构(Sponge)教学实现 ==
absorb(hello world) 后 squeeze 8B : 098d3d0133a31417
同输入 squeeze 32B(XOF 任意长) : 098d3d0133a314179705a524f08b5a3f...
改 1 比特输入后 squeeze 8B : 48bfe0d5f5a0b47d (完全不同)
== 雪崩效应: 输入翻转 1 比特, 输出应约半数比特翻转 ==
SHA-256 平均翻转 128.7 / 256 bit (50.3%)
SHA3-256 平均翻转 127.6 / 256 bit (49.8%)
BLAKE2s 平均翻转 128.9 / 256 bit (50.3%)
== 长度扩展攻击对比 ==
MD 结构 : 攻击者续算的伪造值与真实值相等? True -> 长度扩展攻击成功(危险!)
海绵结构 : 攻击者续算的伪造值与真实值相等? False -> 结构性免疫
PASS: 海绵结构可吸收可挤压且免疫长度扩展; 三大算法雪崩均达标
五、结果解读
- 海绵结构的两阶段与 XOF 特性:同一份输入先挤压 8 字节再挤压 32 字节,前 8 字节完全一致——输出确实是从同一状态连续挤出来的;改动输入一个比特,输出完全不同。
- 雪崩效应全部达标:三大算法实测翻转率均在 50% 附近(128/256),这是严格雪崩准则(SAC)的经验验证——输出每个比特以一半概率翻转,输入的任何局部变化都被放大为输出的全局混乱。
- 长度扩展攻击的对比是本文最核心的实证:MD 结构上攻击者用截获哈希当状态成功续算出伪造值,海绵结构上同样的尝试失败。这不是实现差异,是结构差异——MD 把完整内部状态暴露为输出,海绵只暴露速率部分。
- 两次有教学价值的修复:初版雪崩测试先翻转比特再取基线,导致两次哈希的是同一份数据、翻转数恒为 0——测量基线必须先于扰动建立;长度扩展演示初版忽略了末块补零填充,伪造与真实两侧块序列对不齐——真实攻击中攻击者必须把『胶水填充』计入扩展消息,这与 MD5/SHA-1 时代真实漏洞利用的细节完全一致。
六、工程应用
- SHA-3 家族:SHA3-224/256/384/512 定长输出,SHAKE128/256 是 XOF(任意长输出),cSHAKE 支持域分离定制;KMAC 是基于海绵的 MAC,结构上优于 HMAC;
- BLAKE3 的典型用途:文件完整性校验(大文件并行哈希碾压 SHA-2)、内容寻址存储(IPFS 生态)、区块链 Merkle 树(树形结构天然契合);
- 密钥派生:HKDF(HMAC 族)与 KMAC(海绵族)是两条主流路线;密码哈希请专用 Argon2/scrypt/bcrypt,通用哈希函数再快也不适合存密码;
- MAC 的正确姿势:用 SHA-2 做消息认证必须 HMAC,不能密钥拼接(本文实验已演示为什么);用 SHA-3/BLAKE3 则可直接 KMAC/ keyed 模式。
七、常见误区
- 用通用哈希存密码:SHA-256 再快也是缺陷而非优点——密码哈希需要刻意缓慢+加盐(Argon2id 是当前推荐)。
- 密钥拼接当 MAC:H(secret||msg) 在 MD 结构上直接可被长度扩展攻击(本文实测);要么 HMAC,要么用结构上免疫的海绵/BLAKE3 keyed 模式。
- 以为 SHA-3 是 SHA-2 的替代品:NIST 定位是『备份与补充』——SHA-2 至今无实际碰撞,SHA-3 的价值在于完全不同的结构多样性;实际选型中 SHA-256 仍是默认答案。
- 忽视截断输出的碰撞界:256 位输出截断到 128 位,抗碰撞强度从 2^128 降到 2^64——截断不是免费的。
- 在非并发场景用 BLAKE3 期待加速:BLAKE3 的并行优势在大文件多核场景才显现;小消息上单线程性能与 BLAKE2s 相当。
八、参考文献
- Bertoni, G. et al. Keccak (SHA-3). NIST FIPS 202, 2015.
- O'Connor, J. et al. BLAKE3: One Function, Fast Everywhere. IACR ePrint 2020/530.
- Aumasson, J.-P. et al. BLAKE2: Simpler, Smaller, Fast as MD5. ACNS 2013.
- Bertoni, G. et al. Cryptographic Sponge Functions. 2011(海绵结构理论基础).
- NIST. SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. FIPS 202.