首页/安全/加密与证书速查/长度扩展与哈希构造选择
加密算法基础95 条

长度扩展与哈希构造选择

对 Merkle–Damgård 类哈希(MD5/SHA-1/SHA-2),在只知道 H(secret||msg) 与长度时可推导出更长消息的摘要;HMAC 与 SHA-3/BLAKE2 不受影响。

加密与证书速查安全更新于 2026-10-13

长度扩展问题是什么

对采用迭代压缩结构的哈希,如果只把密钥拼在消息前面再发布整体摘要,攻击者已知消息长度时可以从该摘要推导出「更长消息」的合法摘要。修复方式是使用密钥化构造,或改用不受影响的哈希结构。这个问题只影响自研的拼接式认证,标准协议与成熟库的实现不受影响。

基本信息

受影响采用迭代压缩结构的哈希算法
不受影响海绵结构与树结构哈希
防护使用密钥化构造
典型误用把密钥直接拼在消息前面再取摘要

典型使用场景

  • 接口签名审计:检查是否存在密钥直接拼接的写法
  • 自研协议评审:确认认证值的构造方式
  • 代码迁移:把拼接式校验改造为标准构造
  • 排错:确认签名校验失败是否与构造方式有关
  • 协议对接:双方需同时更换构造方式

安全写法

安全写法
import hmac, hashlib
# 不要使用:hashlib.sha256(secret + data).hexdigest()
tag = hmac.new(secret, data, hashlib.sha256).hexdigest()   # 标准密钥化构造
hmac.compare_digest(tag, received)                         # 校验用常量时间比较

构造方式对比

构造是否受影响说明
密钥拼在消息前受影响可从摘要扩展出更长消息
密钥拼在消息后不直接受影响仍有其他风险,不建议
密钥化构造不受影响按标准实现,推荐
海绵结构哈希不受影响结构本身不受该问题影响
该问题只影响「密钥与消息拼接」的自研构造;标准协议与成熟库的密钥化实现不受影响,审计时重点看拼接方式即可快速判断。

落地建议

  • 统一使用库提供的密钥化构造
  • 校验使用常量时间比较
  • 把拼接式签名的搜寻纳入代码审计规则
  • 协议对接时双方同步切换构造方式
改用不受影响的哈希结构可以规避该问题,但协议对接需要双方同时升级;单侧切换会造成校验全部失败。

易错点

  • 把哈希当消息认证码用,容易忽略密钥前缀构造的顺序问题
  • 改用新结构时只改一侧,协议对接全部失败
  • 用固定密钥长度假设做防护,实际上攻击者可能已知消息长度
  • 把密钥拼在消息后面视为安全,实际上仍有其他构造风险
  • 只改签名代码而不排查历史数据的兼容性

数据来源与参考

  • RFC 2104(HMAC 设计与长度扩展背景)
  • FIPS 202(海绵结构差异)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌