HMAC-SHA256 生成器
根据消息和密钥生成 HMAC-SHA256 签名。此工具会将两者编码为 UTF-8,使用 SHA-256 应用 RFC 2104 中定义的 HMAC 构造,并以十六进制或 Base64 返回 256 位标签。开发者会用它调试来自 Stripe、GitHub 或 Slack 等服务的 webhook 签名、为 API 请求签名,并将结果与自己的代码进行比较。密钥绝不会被返回或记录。
常见问题
什么是 HMAC-SHA256?
HMAC-SHA256 是由 SHA-256 和密钥构成的消息认证码,定义见 RFC 2104。只有持有密钥的人才能为消息计算出正确的标签。结果为 32 字节,即 64 个十六进制字符。
如何验证 webhook 签名?
将未经修改的原始请求正文粘贴为消息,并将签名密钥作为密钥,然后将结果与签名标头进行比较。许多服务会对组合内容签名,例如 Stripe 的时间戳、一个点号和正文,因此请按照其文档说明构造消息。只要有一个字节发生变化,标签就会不同。
有已知的测试向量吗?
RFC 4231 的测试用例 2 使用密钥 Jefe 和消息 what do ya want for nothing?,预期结果为 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843。此工具返回的结果与之完全一致。
密钥和消息如何编码?
两者都会编码为 UTF-8 文本。如果你的密钥以十六进制或 Base64 格式提供(某些服务会这样做),其字节与所见文本不同,因此你需要先在自己的代码中解码密钥。两个字段中的空格和换行都会计入。
我的密钥会被存储吗?
不会。密钥仅用于在请求期间计算标签,不会包含在响应中,也不会被记录或存储。
密钥可以为空或很长吗?
HMAC 接受任意长度的密钥,包括空密钥。根据 RFC 的规定,超过 64 字节的密钥会先使用 SHA-256 进行哈希。实际使用时,请选择至少 32 字节的随机密钥。
我应该选择十六进制还是 Base64?
请使用对方发送的格式。GitHub 和 Stripe 使用十六进制;Slack 会在十六进制前加上 v0=,而许多基于 AWS 和 JWT 的系统使用 Base64。两种格式编码的都是相同的 32 个字节。
HMAC-SHA256 和将密钥与消息拼接后进行 SHA-256 是一样的吗?
不一样。HMAC 会使用经过填充的内层和外层密钥对消息进行两次哈希,从而防止长度扩展攻击。将密钥与消息拼接后只哈希一次,结果不同且安全性较弱。
在代码中应该如何比较签名?
请使用恒定时间比较函数,例如 Node.js 中的 crypto.timingSafeEqual,或 Python 中的 hmac.compare_digest。普通字符串比较可能会泄露预期标签的计时信息。
消息最大可以有多大?
消息和密钥的总大小最多可为 5 MiB 文本。这足以应对典型的 webhook 负载和 API 请求。