需要 FIPS 合规时该选哪个哈希

工具相关 ·

做面向政府、金融或医疗行业的项目时,安全方案评审里经常出现一条要求:密码算法必须满足 FIPS 140 认证。这时如果架构里用的是 Argon2id,评审会直接被卡住——不是因为它不安全,而是因为它不在 NIST 的标准算法列表里。合规和「更安全」在这里不是一回事。

FIPS 140 是什么

FIPS 140 是美国联邦信息处理标准中关于密码模块的一份规范,最新版本是 FIPS 140-3。它规定了密码模块在设计、实现、测试方面要满足的要求,由经过认证的实验室进行测试并出具证书。

关键点在于:FIPS 认证的对象是具体的密码模块实现,而不是算法本身。所以「Argon2 安全但不合规」这个说法,准确表述应该是「Argon2 不是 NIST 标准算法,无法纳入 FIPS 认证范围」。

这条要求会层层传导到技术选型上。如果业务需要满足 FIPS 合规,那么用到的每一个密码算法都必须在标准列表内,否则整个模块拿不到认证。

哪些口令哈希符合要求

在常见的三类口令哈希里,只有 PBKDF2 符合要求。

PBKDF2 被 NIST SP 800-132 采纳,并且它的底层使用的是 HMAC,而 HMAC 基于 SHA-1、SHA-256、SHA-512 这些 FIPS 认可的哈希函数。整条链路都在标准范围内,所以可以使用经过验证的 PBKDF2 实现。

Bcrypt 不符合。它基于 Blowfish 分组密码,而 Blowfish 从未被 NIST 标准化。虽然 Bcrypt 在实际使用中表现良好,但它不在 FIPS 的认可列表里。

Argon2 不符合。它是密码哈希竞赛的产物,2017 年发布为 IETF 的 RFC 9106,属于 IETF 标准而非 NIST 标准。所以即使 Argon2id 在抗 GPU 能力上明显更强,也无法用于需要 FIPS 合规的场景。

算法FIPS 合规抗 GPU标准化来源
PBKDF2是弱NIST SP 800-132
Bcrypt否一般事实标准
Argon2否强RFC 9106

选 PBKDF2 之后要注意什么

既然只能用 PBKDF2,那么提升安全性的手段就集中在参数上。

第一,HMAC 算法选 SHA-256 或 SHA-512。虽然 HMAC-SHA1 也在 FIPS 列表里,但 SHA-1 的整体生态正在收缩,新项目没有理由继续使用。SHA-256 是平衡兼容性与强度的选择。

第二,迭代次数按服务器算力实测确定,目标是单次校验 100 到 500 毫秒。OWASP 给 SHA-256 的建议是 60 万次,在普通服务器上约 1.6 秒,实际部署时通常需要下调。合规要求的重点是「有足够的工作因子」,具体数值可以按自己的容量规划确定。

第三,盐值至少 16 字节,由密码学安全的随机源生成。NIST SP 800-132 对盐长度有明确要求,这一点在评审时会被检查。

第四,输出长度至少 32 字节(256 位)。这是与安全强度直接相关的参数,不要为了节省存储而缩短。

一个折中方案

有些系统同时面对两类要求:既要满足合规,又希望在非合规场景下获得更强的保护。

可行的做法是在架构里把口令哈希抽象成一层接口,按部署环境选择实现。在需要 FIPS 合规的部署里使用 PBKDF2,在其他部署里使用 Argon2id。存储格式统一采用 PHC 串,因为串里写明了算法,校验函数可以按串自动分派。

不过这个方案有明显的代价:两条代码路径都要测试,参数都要调优,迁移时要考虑数据格式互通。如果业务并不真的需要区分环境,引入这种复杂度往往得不偿失。

更常见的处理方式是:如果合规是硬要求,就统一用 PBKDF2,把参数调到位,接受抗 GPU 能力弱一些的事实;如果合规只是「最好能满足」,就优先用 Argon2id,在评审时说明技术理由。

检查清单

  • FIPS 认证的对象是密码模块实现,不是算法本身,但算法必须在标准列表内
  • 三类口令哈希中只有 PBKDF2 符合要求,它被 NIST SP 800-132 采纳
  • Bcrypt 基于未标准化的 Blowfish,Argon2 属于 IETF 标准,都不在列表内
  • 选 PBKDF2 后用 HMAC-SHA256 或 SHA-512,迭代次数按实测确定
  • 盐至少 16 字节,输出至少 32 字节,两者都要满足 NIST 要求
  • 需要同时满足两类要求时可以把哈希实现抽象成接口,但要注意测试与迁移成本
阅读 11