哈希与安全

HMAC 生成器

根据消息和密钥生成 HMAC 签名。

给这个工具评分

如何使用 HMAC 生成器

  1. 粘贴您要签名的消息。
  2. 输入双方共享的密钥。
  3. 选择一种算法——如不确定请选 HMAC-SHA-256——然后复制结果。

关于 HMAC 生成器

HMAC 代表 Hash-based Message Authentication Code(基于哈希的消息认证码),定义于 RFC 2104。它在哈希计算过程中混入了一个密钥,而这一处添加改变了输出所能证明的内容。普通哈希只能证明某些数据产生了某个摘要——如果攻击者能够篡改消息,他们完全可以重新计算哈希来与之匹配,不会露出任何破绽。有了 HMAC,他们无法在不知道密钥的情况下生成有效的验证码,因此接收方同时获得了完整性(消息未被篡改)和真实性(消息确实来自持有密钥的一方)这两项保证。

HMAC 并不只是“把密钥和消息一起哈希”这么简单——它采用了一种嵌套结构,用两个派生密钥值进行两次哈希。正是这种结构使 HMAC 免受长度扩展攻击的影响,而原始的 SHA-256 和 SHA-512 却会受到这种攻击的影响:攻击者只要知道一个摘要,就能在不知道原始输入的情况下追加数据并计算出一个有效的新摘要。这正是朴素的 hash(密钥 + 消息) 方案会失败、而 HMAC 不会的真正原因。

你几乎肯定在不知不觉中用过 HMAC。Stripe 和 GitHub 的 webhook 签名就是 HMAC——你用来比对的请求头,正是根据原始请求体和你的签名密钥计算出来的。AWS 的请求签名也用到了它。使用 HS256 签名的 JWT 同样如此,你可以用我们的 JWT 解码器把它拆开来看。HMAC-SHA-256 是通常的默认选择,也是新项目的正确选项。HMAC-MD5 是个有趣的特例:尽管 MD5 存在碰撞弱点,它作为 MAC 仍被认为是可以接受的,因为 HMAC 的安全性并不依赖于抗碰撞性——但这并不意味着在新设计中选择它有什么充分理由。

常见问题

HMAC 和普通哈希有什么区别?

如果攻击者能够篡改消息,普通哈希什么也证明不了,因为他们同样能重新计算哈希。HMAC 混入了一个密钥,因此只有持有密钥的人才能生成有效的验证码——这样你就同时获得了真实性和完整性保证。

我应该选择哪种算法?

除非有特殊原因,否则请使用 HMAC-SHA-256——它是 webhook、API 签名和 JWT HS256 的通用默认选择。

HMAC-MD5 安全吗?

尽管 MD5 本身已在碰撞方面被攻破,但作为 MAC 使用它仍被认为是可以接受的,因为 HMAC 并不依赖抗碰撞性。话虽如此,新设计不要选它——请使用 HMAC-SHA-256。

为什么我的 webhook 签名对不上?

几乎总是因为消息字节不一致。请对完全原始的请求体进行签名——而不是重新序列化后的版本——并检查是否有多余的换行符,或密钥编码方式是否不同。

我的消息和密钥会被存储吗?

不会。两者都会被发送到我们的服务器,因为浏览器无法计算其中大部分算法,计算完成后会立即用于运算并丢弃——绝不记录,绝不存储。对于正在使用的生产签名密钥,在自己的机器上完成这项操作仍然是更安全的习惯。