什么是 HMAC
HMAC(Hash-based Message Authentication Code,基于哈希的消息认证码)是一种使用加密哈希函数和密钥来验证消息完整性和真实性的算法。
简单来说,HMAC 就是"带密钥的哈希"——只有拥有相同密钥的人才能生成或验证 HMAC 值。
HMAC vs 普通哈希
| 特性 | 普通哈希(如 SHA-256) | HMAC | |------|----------------------|------| | 输入 | 仅消息 | 消息 + 密钥 | | 无密钥可验证 | ✅ | ❌ | | 防伪造 | ❌(攻击者可自行计算) | ✅(需要密钥) | | 典型用途 | 文件完整性、密码存储 | API 签名、消息认证 |
HMAC 的工作原理
HMAC 的计算公式:
HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
其中:
K= 密钥(Key)m= 消息(Message)H= 哈希函数(如 SHA-256)K'= 密钥处理(过长则哈希,过短则填充)opad= 外部填充(0x5c 重复)ipad= 内部填充(0x36 重复)
如何使用在线 HMAC 生成器
使用 DevToolkit Pro 的 HMAC 生成器:
- 输入密钥(Key)
- 输入消息(Message)
- 选择哈希算法(SHA-256 / SHA-512 / SHA-1 / MD5)
- 点击 Generate 按钮
- 复制生成的 HMAC 值
HMAC 的常见应用场景
1. API 请求签名
许多 API(如 AWS、Stripe、微信支付)要求请求携带 HMAC 签名:
// 请求头示例
Authorization: HMAC-SHA256 signature=abc123...
服务端用相同密钥对请求参数计算 HMAC,与客户端提交的签名对比,验证请求未被篡改。
2. Webhook 验证
GitHub、Stripe 等平台的 Webhook 使用 HMAC-SHA256 签名验证:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
3. JWT 签名
JWT(JSON Web Token)的 HS256 算法本质上就是 HMAC-SHA256:
header.payload.signature
其中 signature = HMAC-SHA256(base64(header) + "." + base64(payload), secret)
4. 消息完整性校验
在不可信网络中传输消息时,附带 HMAC 可以验证消息未被篡改。
HMAC 密钥安全建议
- 密钥长度:至少 256 位(32 字节),推荐使用密码学安全随机数生成
- 密钥存储:不要硬编码在源代码中,使用环境变量或密钥管理服务
- 密钥轮换:定期更换密钥,使用新密钥验证前一个周期的请求
- 时间戳防重放:在签名消息中包含时间戳,拒绝过期请求
FAQ
HMAC 和数字签名有什么区别?
HMAC 使用对称密钥(同一密钥生成和验证),数字签名使用非对称密钥(私钥签名,公钥验证)。HMAC 更快,但无法向第三方证明签名来源。选择取决于是否需要不可否认性。
用哪个哈希算法最好?
推荐 HMAC-SHA256,它是目前最广泛使用的标准。SHA-1 和 MD5 已被认为不安全,不应在新项目中使用。
HMAC 可以防止重放攻击吗?
单独不行。HMAC 只验证消息完整性,不防止重放。需要结合时间戳(timestamp 参数)或随机数(nonce)来防重放。
本文由 DevToolkit Pro 提供。更多开发者工具请访问 首页。