HMAC、PBKDF2 与 HKDF 计算器

用 HMAC-MD5、HMAC-SHA-1、HMAC-SHA-256、HMAC-SHA-384 或 HMAC-SHA-512(RFC 2104)对文本、hex 字节或整个文件计算带密钥的消息认证码 —— 密钥支持文本、hex 或 Base64。也可以用 PBKDF2(RFC 8018)和 HKDF(RFC 5869)派生密钥。每个结果都可以渲染为 hex、大写 hex、Base64 或 Base64url。纯摘要请看哈希生成器;校验和请看CRC 计算器;JWT 里的 HMAC 请看JWT 解码器。
完全本地运行 —— 密钥和消息永远不会离开你的标签页。文件最大 200 MB。
构造: 输出:
HMAC 算法: RFC 2104 — MD5 变体需要 md5.js(本页已加载)。
Hex 读取方式容忍空格、冒号和 0x 前缀;Base64 须为标准格式(带或不带填充)。
空密钥在 RFC 2104 下合法但几乎总是错误 —— 没有密钥的 HMAC 只是一个慢哈希。
第一行记录所用的确切参数(算法、读取方式、输入大小),因此复制粘贴出的结果总是可复现的。
你需要哪种构造?
HMAC 把共享秘密加上消息变成一个认证器:持有密钥的接收方可以重算它并检测篡改。它就是每份签名 JWT 里的“HS256”(见JWT 解码器),也是世界上大半 API 请求签名方案的一半。PBKDF2 用于把人类口令拉伸成密钥:它把 HMAC 重复数千次,使攻击者猜测每个口令都要付出同样的延迟。HKDF 面向协议密钥:它接收已经随机的保密字节(如 DH 共享秘密),安全地扩展成多个绑定用途的密钥 —— TLS 1.3 的全部流量密钥就是这样派生的。经验法则:认证 → HMAC;口令 → PBKDF2(或 scrypt/Argon2,发布后见密码哈希生成器);均匀秘密 → HKDF。
自测
用已发表的向量测试本页引擎:10 个 HMAC 锚点(RFC 2202/4231 风格,五种算法 × 两种输入)、6 个 PBKDF2 锚点(SHA-1 和 SHA-256 各三个迭代次数)以及 RFC 5869 HKDF 的四个测试用例 A.1–A.4。任何数据都不会被发送。
HMAC、PBKDF2 与 HKDF —— 从零讲清带密钥哈希
一句话:像 SHA-256 这样的裸哈希谁都能算,所以它证明不了消息是谁发的 —— HMAC 混入一个秘密密钥,使只有持有密钥的人才能产生(或验证)摘要;PBKDF2 和 HKDF 则复用同一套 HMAC 机器,把秘密变成密钥:对口令要慢,对已随机的材料要快。
HMAC 是什么(RFC 2104)

构造。HMAC 是两次哈希,不是一次。密钥被填充到哈希的块大小(MD5/SHA-1/SHA-256 为 64 字节,SHA-384/512 为 128 字节);消息先与“密钥 XOR 固定内层填充”一起哈希一次,得到的摘要再与“密钥 XOR 固定外层填充”哈希一次。只要底层哈希是像样的伪随机函数,这个双夹层就被证明是安全的 —— 这也是 HMAC-MD5 至今仍能抵御攻破裸 MD5 的实用碰撞攻击的原因(尽管它反正已经退役,见下文)。

密钥。任意长度都可以:短于块大小的直接使用(但不足 32 字节会被人皱眉),更长的会先被哈希。本页允许把密钥按文本、hex 或 Base64 输入,这样 64 个 hex 字符的生产密钥不会被误当 64 字符的文本口令粘贴 —— 输出行里记录读取方式正是为了这个。

在哪里会遇到它。JWT 头部的 HS256 字段就是对 base64url 编码的令牌部分做 HMAC-SHA-256(粘贴 HS256 密钥时,本站的JWT 解码器算的正是它)。Webhook 签名(Stripe、GitHub)、AWS SigV4、TLS 记录保护(旧版本)以及 OpenSSH 的近亲 umac-64@openssh.com 都属于同一家族。

为什么不直接 hash(message || key)?长度扩展攻击:MD5/SHA-1/SHA-2 家族的每种哈希都允许知道 H(secret || msg) 的攻击者在没有秘密的情况下算出 H(secret || msg || padding || anything)。HMAC 的内外分层消灭了这一类攻击。这是 API 签名代码里最常见的 DIY 错误 —— 也是 HMAC 存在的理由。

PBKDF2 是什么(RFC 8018)

慢是设计出来的。一个口令可能只有 40 比特的真实熵;攻击者的 GPU 每秒能试数十亿次裸 SHA-256。PBKDF2 把 HMAC(password, salt) 反复运行 —— iter 次 —— 让你和攻击者每次猜测付出同样的 iter 次 HMAC。这里的默认值是 HMAC-SHA-256 的 600,000 次迭代,即 OWASP 口令存储速查表的基线;滑块上限一千万,因为随着硬件提速,安全建议也会不断上调。

盐。每口令的随机盐让相同口令的用户不再哈希出相同结果,预计算表(彩虹表)也就失效了。盐不是秘密 —— 它就存在哈希旁边 —— 它只需要唯一。16 个随机字节是惯例。

已知弱点。PBKDF2 抗 CPU 但不抗内存:GPU 和 ASIC 并行化它毫不费力。所以在设计口令哈希存储时,现代建议是 scrypt 或 Argon2id(本家族的密码哈希生成器页面覆盖了它们),而 PBKDF2 仍是兼容性与 FIPS-140 场景的正确答案。

HKDF 是什么(RFC 5869)

先提取,再扩展。HKDF 做两件事。Extract:把可能不均匀的输入密钥材料(例如 Diffie–Hellman 共享秘密)与盐一起压成一个短的伪随机密钥 PRK = HMAC(salt, IKM)。Expand:把 PRK 拉伸到最多 255 个哈希块的任意长度,每个输出块与前一块链式相连并由 info 字段标记用途。结果是一个秘密可以安全地派生出加密密钥、MAC 密钥和 IV,彼此分离。

不适用于口令。HKDF 假定输入已有充分熵 —— 它每 32 个输出字节只做一次 HMAC,人类口令几乎瞬间穿过它,这正是攻击者想要的。用 HKDF 而不是 PBKDF2 处理口令是经典设计错误;info 字段是用途标签("client traffic key"、"server iv"),不是额外熵。

在哪里会遇到它。TLS 1.3 从握手秘密经 HKDF 派生它使用的每一个密钥;WireGuard、Signal、EAP-TLS 1.3 和 JSON Web Encryption(作为直接密钥协商 KDF)都在同一棵家族树上。

锚点值 —— 在本页复现它们

前两张表是本页样例按钮和自测所用的测试向量(密钥 "key"、消息“The quick brown fox jumps over the lazy dog”;然后是 RFC 风格的 16 字节 0x0b 密钥与消息“Hi There”)。全部由独立原生实现生成,并在本页复核。

“fox” 的 HMAC,密钥 = key摘要(hex)
HMAC-MD580070713463e7749b90c2dc24911e275
HMAC-SHA-1de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC-SHA-256f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC-SHA-384d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237
HMAC-SHA-512b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a
KDF 锚点参数输出(hex,首字节)
PBKDF2-HMAC-SHA-1password / salt,c=4096,32 字节4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db
PBKDF2-HMAC-SHA-256password / salt,c=4096,32 字节c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a
HKDF-SHA-256 (RFC 5869 A.1)IKM=0x0b×22,盐=00..0c,info=f0..f9,L=423cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
HKDF-SHA-256 (RFC 5869 A.2)IKM=00..4f,盐=60..af,info=b0..ff,L=82b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c…
HKDF-SHA-256 (RFC 5869 A.3)IKM=0x0b×22,空盐与空 info,L=428da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
常见误区
  • 把 HMAC 当加密。HMAC 证明完整性与来源(给定共享秘密);它不隐藏任何东西。没有密钥的人仍然能看到完整消息。
  • 把 HMAC 当签名。数字签名是公钥的:一人签名,任何人可验证。HMAC 是对称的:每个验证者同样能伪造。不可抵赖需要 RSA/ECDSA(本家族的 RSA 工具发布后可用),不是 HMAC。
  • 密钥读取方式不匹配。把 64 字符的 hex 串按文本粘贴进密钥框会变成 64 字节而不是 32 —— HMAC 完全不同。本页在输出行打印读取方式;两个工具结果不一致时,先比这一项。
  • PBKDF2 迭代次数太低。2000 年时 1,000 次还算合理;今天的 GPU 集群秒杀它。如果你的系统还在存 1,000 次迭代的哈希,规划一次“登录时重哈希”的迁移吧。
  • 对口令用 HKDF。每个输出块一次 HMAC 意味着口令瞬间通过 —— 口令用 PBKDF2(或 Argon2id),高熵秘密才用 HKDF。
  • 一个派生密钥处处用。修复是免费的:用不同的 info 标签派生独立的密钥。同一 IKM 不同标签派生的两个密钥在设计上就是独立的。
常见问题

HMAC-MD5 被破了吗?作为抗碰撞哈希,MD5 已经死了,但 HMAC-MD5 的安全性取决于 MD5 作为伪随机函数的表现,尚无已知实用破解。反正也退役了 —— 除非为了兼容旧协议,没有理由在 HMAC-SHA-256 可用时选它。

HMAC 密钥该多长?至少等于哈希输出长度(SHA-256 为 32 字节),并由 CSPRNG 生成。短于摘要长度的密钥允许使用,但每一位不足都直接降低安全性。

PBKDF2 迭代越多就越“安全”吗,可以无限加?它线性提高攻击者的成本,但也线性提高你的登录成本。博弈在于选择用户能容忍的最大次数 —— OWASP 的数字就是按这个校准的。

为什么 HKDF 上限是 255 × 哈希长度?扩展循环是 T(i) = HMAC(PRK, T(i-1) || info || i),计数器 i 只有一个字节 —— 255 是最大计数值,这是 RFC 5869 的硬性结构限制,不是策略选择。

本页的 PBKDF2 和密码哈希生成器有什么区别?同一算法,不同工作。本页派生原始密钥字节供你在别处使用;密码哈希页生成的是存储凭据字符串(内嵌盐与参数),并对照它们验证粘贴的候选口令。