HMAC 介绍
文章目录
- 1.简介
- 2.工作原理
- 3.应用场景
- 3.1 API 请求认证
- 3.2 一次性密码基础(One-Time Password,OTP 底层)
- 3.3 用户密码存储
- 3.4 会话令牌(Token)防篡改
- 3.5 区块链交易验证
- 4.优势与局限性
- 5.代码示例(Python)
- 6.注意事项
- 7.小结
- 参考文献
1.简介
HMAC(Hash-based Message Authentication Code) 是一种基于哈希函数的消息认证码技术,用于同时验证数据完整性(Integrity)和身份真实性(Authentication)。其核心原理是通过密钥(Secret Key)与原始数据混合运算生成防篡改的签名,确保消息在传输中未被修改且来源可信。
2.工作原理
HMAC = Hash( (Key ⊕ opad) || Hash( (Key ⊕ ipad) || Message ) )
- Key:双方共享的密钥(需保密)。
- ipad / opad:固定填充常量(0x36 和 0x5C)。
- Hash:哈希算法(如 MD5、SHA-256 等)。
- Message:待认证的数据。
- ⊕ 表示异或运算(XOR, Exclusive OR)。
- || 密码学和数据处理中,|| 表示 字节连接(byte concatenation) 操作。
计算步骤:
-
密钥补位:若密钥长度不足,补0至哈希函数要求的块长度。
-
内层哈希:计算 Hash(Key ⊕ ipad || Message)。
-
外层哈希:计算 Hash(Key ⊕ opad || 内层哈希结果) → 生成最终 MAC 值(固定长度)。
以 SHA1 为例,加密示意图如下:
3.应用场景
3.1 API 请求认证
场景:客户端调用服务端 API 时防篡改。
流程:
客户端用密钥生成 HMAC(请求参数),将结果放入请求头(如 X-Signature: sha256=xxxx)。
服务端用相同密钥和参数重新计算 HMAC,比对签名是否一致。
案例:AWS API 签名、微信支付回调验证。
3.2 一次性密码基础(One-Time Password,OTP 底层)
场景:HOTP(HMAC-based OTP)算法。
流程:
HOTP = Truncate( HMAC(SecretKey, Counter) ) → 生成6-8位动态密码
案例:银行U盾、Google Authenticator 的计数器模式。
3.3 用户密码存储
HMAC 可以用于安全地存储用户密码。用户密码不直接存储,而是与一个随机生成的盐值(salt) 结合,然后使用 HMAC 算法生成签名存储。
当用户登录时,服务器使用相同的盐值和 HMAC 算法计算密码的签名,并与存储的签名进行比较,验证用户身份。
3.4 会话令牌(Token)防篡改
场景:JWT(JSON Web Token)的签名部分。
JWT 的三个部分依次如下:
Header.Payload.Signature
更详细的构成如下:
# JWT 头部 + 负载 + HMAC签名
token = base64(header) + "." + base64(payload) + "." + base64(HMAC(密钥, header.payload))
服务端通过验证 HMAC 判断 Token 是否被篡改。
3.5 区块链交易验证
场景:验证交易发起者身份及数据完整性。
案例:Hyperledger Fabric 中的节点通信使用 HMAC 保护消息。
4.优势与局限性
优势 | 局限性 |
---|---|
✅ 抗碰撞攻击:依赖哈希函数强度 | ❌ 密钥管理复杂:密钥泄露=系统沦陷 |
✅ 高效计算:对称加密速度快 | ❌ 无不可否认性:双方持有密钥,无法追溯责任人 |
✅ 防重放攻击:可结合时间戳/计数器 | ❌ 不加密数据:仅认证,需配合TLS等加密通道 |
5.代码示例(Python)
import hmac
import hashlibkey = b'secret_key' # 密钥(需安全存储)
message = b'critical_data' # 待保护数据# 计算 HMAC-SHA256
hmac_digest = hmac.new(key, message, hashlib.sha256).hexdigest()
print("HMAC:", hmac_digest) # 输出:64位十六进制字符串# 验证步骤
def verify_hmac(key, message, received_digest):new_digest = hmac.new(key, message, hashlib.sha256).hexdigest()return hmac.compare_digest(new_digest, received_digest) # 防时序攻击的安全比对is_valid = verify_hmac(key, message, hmac_digest)
print("验证结果:", is_valid) # True
6.注意事项
-
密钥强度:密钥长度 ≥ 哈希函数输出位(如 SHA-256 需 256 位密钥)。
-
哈希算法选择:弃用 MD5/SHA-1,优先选 SHA-256 或 SHA-3。
-
防时序攻击:使用 hmac.compare_digest()(Python)等安全比对函数。
-
密钥轮换:定期更新密钥以降低泄露风险。
7.小结
HMAC 通过“密钥+哈希”的简洁设计,为数据认证提供了高性价比的解决方案,是网络安全(如 API 防护)、身份认证(如 OTP)的基石技术。其安全性依赖于密钥保密性和哈希算法的抗碰撞能力。
参考文献
HMAC - wikipedia