HMAC Generator

使用SHA-256、SHA-384或SHA-512生成HMAC签名

算法

消息

本地运行 · 粘贴密钥安全无忧

密钥

本地运行 · 粘贴密钥安全无忧

HMAC签名

HMAC签名将显示在这里…

什么是HMAC?

HMAC(基于哈希的消息认证码)是RFC 2104中定义的一种密码学结构,它将哈希函数与密钥结合,生成固定长度的认证标签。与任何人都能计算的普通哈希不同,HMAC只能由共享密钥的双方生成和验证。HMAC是同时验证消息完整性和真实性的标准机制——确认数据未被篡改,且来自可信发送方。

HMAC算法可与任何迭代哈希函数配合使用:SHA-256、SHA-384、SHA-512,乃至SHA-1或MD5等旧版函数。所得结构以其底层哈希命名——HMAC-SHA256、HMAC-SHA384或HMAC-SHA512。由于HMAC的安全性证明依赖于哈希函数具备抗碰撞性和伪随机特性,SHA-2系列算法是新系统的推荐选择。HMAC-SHA256是部署最广泛的变体,用于AWS Signature V4、Stripe webhook、GitHub webhook密钥、Slack请求签名及JSON Web Token(HS256)。

HMAC的设计提供了普通哈希所缺乏的关键特性:对长度扩展攻击的抵抗能力。仅使用SHA-256时,知道H(message)的攻击者无需知道原始消息即可计算H(message || attacker_data)。HMAC的双重哈希结构(使用不同填充密钥的内层哈希和外层哈希)完全消除了这种攻击。这正是API签名方案使用HMAC而非简单地将密钥附加到消息后再哈希的原因。

为什么使用在线HMAC生成器?

计算HMAC签名通常需要编写代码或使用命令行工具。这个基于浏览器的HMAC生成器让你无需安装软件或切换到终端,即可立即生成HMAC-SHA256、HMAC-SHA384和HMAC-SHA512签名。

即时HMAC计算
输入消息和密钥,选择哈希算法,立即获得HMAC签名。Web Crypto API在浏览器中原生处理计算。
🔒
隐私优先处理
消息和密钥不会离开你的设备。所有HMAC计算通过Web Crypto API在本地运行——无服务器请求,无日志记录,无数据留存。
📋
多算法支持
一键切换HMAC-SHA256、HMAC-SHA384和HMAC-SHA512。跨算法比较输出结果,验证后端实现是否与之匹配。
🔍
无需账号或安装
在任何现代浏览器中均可使用——Chrome、Firefox、Safari、Edge。无需注册、无需扩展、无需配置命令行。打开页面即可开始生成HMAC签名。

HMAC生成器使用场景

前端开发者 — Webhook签名验证
Stripe、GitHub和Shopify使用HMAC-SHA256对webhook载荷进行签名。在开发过程中使用本工具根据载荷和密钥计算预期签名,然后与HTTP请求头中的签名进行比对。
后端工程师 — API请求签名
AWS Signature V4在签名流程的多个阶段需要HMAC-SHA256。在开发过程中生成参考HMAC值,以调试签名不匹配问题并验证中间计算步骤。
DevOps — 密钥轮换验证
轮换webhook密钥或API签名密钥时,使用新旧密钥分别计算HMAC签名,在旧密钥过期前确认应用能正确处理过渡。
QA工程师 — 签名测试向量
使用已知输入和密钥生成HMAC测试向量,为认证中间件构建回归测试。验证实现是否正确处理空消息、Unicode输入和长密钥。
数据工程师 — 消息管道认证
为事件驱动管道(Kafka、SQS)中的消息附加HMAC签名,验证消息在服务间传输过程中未被篡改。
学生 — 密码学课程学习
通过HMAC实验理解消息或密钥中单个字符的变化如何产生完全不同的签名。将HMAC输出与普通SHA-256输出进行比较,观察密钥带来的差异。

HMAC vs 普通哈希 vs 加密

HMAC、普通哈希和加密各有不同用途。HMAC提供消息认证——证明消息由持有密钥的人创建且未被修改。普通哈希提供完整性但不提供认证。加密提供机密性。下表阐明了三者的区别。

属性HMACPlain HashEncryption
PurposeMessage authentication + integrityData integrity only (no key)Confidentiality + integrity
Requires secret keyYesNoYes
Verifiable byParties who share the secretAnyoneRecipient with key
ReversibleNo — digest onlyNo — digest onlyYes — decryption recovers data
Output sizeDepends on hash (e.g. 256 bits)Depends on hashVariable (ciphertext)
StandardRFC 2104FIPS 180-4NIST SP 800-38A (AES)
Use case exampleWebhook signature verificationFile checksum verificationEncrypting data at rest

HMAC算法比较

HMAC可使用任何哈希函数,但底层算法的选择决定了输出大小、安全级别和浏览器兼容性。HMAC-SHA256是新系统最常见的选择。下表比较了你可能遇到的各种变体。

算法摘要大小十六进制长度Web Crypto API适用场景
HMAC-SHA256256 bits64 hex charsYesAPI signing, webhooks, JWT (HS256)
HMAC-SHA384384 bits96 hex charsYesTLS 1.3 PRF, CNSA compliance
HMAC-SHA512512 bits128 hex charsYesHigh-security signatures, HKDF
HMAC-SHA1160 bits40 hex charsYesLegacy OAuth 1.0, TOTP (RFC 6238)
HMAC-MD5128 bits32 hex charsNoLegacy only — not recommended

HMAC内部工作原理

HMAC使用两种不同的密钥派生填充,对底层哈希函数应用两次。该结构定义于RFC 2104,并在标准密码学假设下被证明是PRF(伪随机函数)。密钥首先被填充或哈希,以匹配哈希函数的块大小(SHA-256为64字节,SHA-512为128字节)。

HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
where K' = key padded to block size, ipad = 0x36, opad = 0x5C

算法将填充后的密钥与内层填充常量(ipad,0x36重复填充)进行XOR,与消息拼接后求哈希。然后将填充后的密钥与外层填充常量(opad,0x5C重复填充)进行XOR,与内层哈希输出拼接后再次求哈希。这种双重哈希结构正是防止长度扩展攻击、并确保HMAC输出在不知道密钥的情况下无法被计算的原因。

HMAC代码示例

HMAC在所有主流语言和运行时中均有原生支持。Web Crypto API无需任何库即可在浏览器中提供HMAC-SHA256、HMAC-SHA384和HMAC-SHA512。以下示例展示了包括webhook验证和常量时间比较在内的实际使用模式。

JavaScript (Web Crypto API)
async function hmacSHA256(message, secret) {
  const enc = new TextEncoder()
  const key = await crypto.subtle.importKey(
    'raw', enc.encode(secret),
    { name: 'HMAC', hash: 'SHA-256' },
    false, ['sign']
  )
  const sig = await crypto.subtle.sign('HMAC', key, enc.encode(message))
  return Array.from(new Uint8Array(sig))
    .map(b => b.toString(16).padStart(2, '0')).join('')
}

await hmacSHA256('hello world', 'my-secret-key')
// → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"

// Node.js (built-in crypto module)
const crypto = require('crypto')
crypto.createHmac('sha256', 'my-secret-key')
  .update('hello world').digest('hex')
// → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"
Python
import hmac
import hashlib

# HMAC-SHA256
sig = hmac.new(
    b'my-secret-key',
    b'hello world',
    hashlib.sha256
).hexdigest()
print(sig)
# → "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"

# Verify a webhook signature (constant-time comparison)
expected = "90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad"
received = hmac.new(b'my-secret-key', b'hello world', hashlib.sha256).hexdigest()
if hmac.compare_digest(expected, received):
    print("Signature valid")

# HMAC-SHA512
hmac.new(b'key', b'data', hashlib.sha512).hexdigest()
Go
package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "fmt"
)

func main() {
    mac := hmac.New(sha256.New, []byte("my-secret-key"))
    mac.Write([]byte("hello world"))
    sig := mac.Sum(nil)
    fmt.Printf("%x\n", sig)
    // → 90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad

    // Verify: use hmac.Equal for constant-time comparison
    expected := mac.Sum(nil)
    fmt.Println(hmac.Equal(sig, expected)) // true
}
CLI (OpenSSL)
# HMAC-SHA256
echo -n "hello world" | openssl dgst -sha256 -hmac "my-secret-key"
# → SHA2-256(stdin)= 90eb182d8396f16d4341d582047f45c0a97d73388c5377d9ced478a2212295ad

# HMAC-SHA512
echo -n "hello world" | openssl dgst -sha512 -hmac "my-secret-key"

# Verify a file signature
openssl dgst -sha256 -hmac "my-secret-key" release.tar.gz

# HMAC with hex key (e.g. from a webhook secret)
echo -n "payload" | openssl dgst -sha256 -hmac "$(echo -n '736563726574' | xxd -r -p)"

常见问题

HMAC与普通哈希有什么区别?
普通哈希(SHA-256、MD5)仅以消息作为输入,生成任何人都可以计算的摘要。HMAC同时接受消息和密钥,生成只有持有密钥的人才能生成或验证的签名。这意味着HMAC除完整性检查外还提供认证(证明发送方身份)。普通哈希仅能证明数据未被改变,但无法证明是谁生成的。
HMAC-SHA256安全吗?
是的。截至2026年,HMAC-SHA256被认为是安全的。其安全性依赖于SHA-256的伪随机特性和HMAC结构本身(RFC 2104)。尚无针对HMAC-SHA256的实际攻击被证实。即使是HMAC-MD5和HMAC-SHA1在实践中仍然安全,因为HMAC的安全性并不要求底层哈希具有完全的抗碰撞性,不过新系统仍推荐使用SHA-2变体。
为什么webhook使用HMAC而不是加密载荷?
Webhook载荷通常包含接收方已预期的数据——订单详情、事件通知、状态更新。目标不是隐藏数据(机密性),而是证明数据来自合法发送方且在传输过程中未被修改(真实性和完整性)。HMAC以最小开销实现这一目标:发送方使用共享密钥对载荷计算HMAC,并将其包含在HTTP请求头中;接收方重新计算HMAC后进行比对。加密则会增加不必要的复杂性和密钥管理负担。
如何安全地比较HMAC签名?
始终使用常量时间比较函数。Python中使用hmac.compare_digest(),Node.js中使用crypto.timingSafeEqual(),Go中使用hmac.Equal()。标准字符串相等运算符(==或===)会泄露时序信息:攻击者可以测量比较所需时间,从而判断其伪造签名有多少字节与正确签名匹配,然后逐字节暴力破解剩余部分。
能否逆向HMAC以还原密钥?
不能。HMAC基于单向哈希函数,因此没有数学捷径能从HMAC输出中提取密钥。攻击者需要穷举整个密钥空间,对于128位或更长的密钥而言这是不可行的。然而,弱密钥或短密钥(如简单密码)容易受到字典攻击,因此对于HMAC-SHA256,始终应使用至少256位的密码学随机密钥。
如果HMAC密钥长于哈希块大小会怎样?
如果密钥长于哈希函数的块大小(SHA-256为64字节,SHA-512为128字节),HMAC算法会先用底层哈希函数对密钥进行哈希,将其缩短为哈希输出长度,然后以该哈希作为有效密钥。这意味着超长密钥提供的安全性不会超过哈希输出大小。对于HMAC-SHA256,超过64字节的密钥会被哈希为32字节,不比64字节密钥更安全;不超过64字节的密钥则以其完整长度使用。
什么情况下应该使用HMAC-SHA512而不是HMAC-SHA256?
当协议要求使用HMAC-SHA512(某些密钥派生函数如HKDF-SHA512、Ed25519密钥生成),需要更宽签名以实现纵深防御,或在64位硬件上运行且SHA-512实际上比SHA-256更快时,应选择HMAC-SHA512。对于大多数Web应用、API签名和webhook验证,HMAC-SHA256提供了足够的安全性,且在各生态系统中是更通用的选择。