SHAKE 是什么
SHAKE 是 FIPS 202 定义的可扩展输出函数(XOF,eXtendable Output Function):SHAKE128 与 SHAKE256 基于 Keccak 海绵结构,可以在调用时指定任意输出长度,而不像 SHA-256 那样固定输出 32 字节。它的安全强度分别对应 128 位与 256 位,常用于密钥派生、把随机比特扩展到协议要求的长度,以及后量子签名与密钥封装算法内部的哈希与扩展。它属于 SHA-3 家族,可以理解为固定输出长度哈希的推广。
基本信息
| 标准 | FIPS 202 §6.2 |
|---|---|
| 变体 | SHAKE128、SHAKE256(对应 128 / 256 位安全强度) |
| 输出 | 任意长度,由调用方指定(如 xoflen) |
| 常用工具 | openssl dgst -shake256 -xoflen;Python hashlib.shake_256 |
| 与 SHA-3 关系 | 同属 Keccak 家族,SHA3-256 可视为固定长度特例 |
| 抗长度扩展 | 海绵结构天然不受长度扩展攻击影响 |
典型使用场景
- 协议需要比 SHA-256 更长的摘要,或需要从一个输入派生多段密钥流
- 后量子算法内部用于采样、扩展与哈希到定长(如 ML-KEM、ML-DSA)
- 库设计中用同一原语覆盖多种摘要长度需求,减少算法分支
- 需要自定义长度指纹的校验与分析场景(长度必须与对端约定一致)
- 替代「哈希后再拼接」的多段输出写法,减少实现错误
按需输出长度
按需输出长度
openssl dgst -shake256 -xoflen 64 file.bin # 输出 64 字节摘要
# Python
import hashlib
hashlib.shake_256(b'data').hexdigest(64) # 输出 64 字节(hex 128 字符)
hashlib.shake_128(b'data').digest(16) # 输出 16 字节原始数据
# hashlib 的 shake 只能在调用时给长度,不能像 sha256 那样省略SHAKE 与固定哈希
| 对比项 | SHAKE128 / 256 | SHA-256 |
|---|---|---|
| 输出长度 | 调用时指定 | 固定 32 字节 |
| 标准出处 | FIPS 202 | FIPS 180-4 |
| 主要用途 | KDF、PQC 内部、可变长度摘要 | 通用摘要、签名与完整性 |
| 长度关系 | 长输出以短输出为前缀,但适用性仍需协议定义 | 截断使用会削弱强度 |
输出长度属于协议约定:同一输入取 32 字节与取 64 字节虽然存在前缀关系,但双方长度不一致会派生出不同密钥,握手或解密会失败且难以定位。部分旧工具链不支持 -xoflen 选项,脚本化前先确认 openssl 版本。