前言
本文主要介绍 HMAC 相关的知识。 看完你将可以用自己的语言向别人解释:啥是 HMAC
正文
初印象
HMAC 怎么读?
HMAC 的标准读法是:/ˈeɪtʃ.mæk/ (谐音:"艾奇-麦克")
HMAC(Hash-based Message Authentication Code,基于【哈希】(注意,不是基于【加密】的!!)的消息认证码)是一种用于【验证消息完整性】和【真实性】的技术。
它结合了加密哈希函数【Cryptographic Hash Function】(如 SHA256、MD5)和一个秘密密钥(Secret Key)。
简单来说,HMAC 可以确保:
完整性:消息在传输过程中没有被篡改。
真实性:消息确实来自拥有共享秘密密钥的声称者。
它常用于 API 签名、JWT(JSON Web Tokens)、安全通信协议等场景。
工作流程
HMAC 的工作过程可以分为三个核心步骤:
首先,发送方将【原始消息】与一个【共享的密钥】进行混合,通过特定的哈希算法(如 SHA-256)生成一段固定长度的【认证码(HMAC 值)】。这个过程中,密钥确保了生成结果的唯一性。
接着,发送方将【原始消息】和【计算出的 HMAC 值】一起传输给接收方。
最后,接收方使用相同的密钥和哈希算法对收到的消息重新计算 HMAC 值。通过比对计算出的 HMAC 与接收到的 HMAC 是否完全一致,来验证消息在传输过程中是否被篡改以及是否来自合法的发送方。任何对消息或密钥的修改都会导致验证失败。
这时候你可能会说,我管你这的那的,给我上图!!
ok,这就上图!!
text
【发送方】
├─ 输入: [密钥] + [原始消息]
├─ 处理: HMAC = Hash(密钥, 消息)
└─ 发送: ┌─────────────┐
│ 原始消息 │
│ HMAC值 │
└─────────────┘
|
↓ 【传输】→ (可能被篡改)
|
【接收方】 ↓
├─ 接收: ┌─────────────┐
│ │ 收到消息 │
│ │ 收到HMAC │
│ └─────────────┘
├─ 处理: HMAC' = Hash(密钥, 收到消息)
├─ 比对: [HMAC'] vs [收到HMAC]
└─ 结果:
├─ 相同 → ✅ 验证成功 (消息完整可信)
└─ 不同 → ❌ 验证失败 (消息被篡改)
关于 HMAC 值
疑问:所以 HMAC 值总结来说算是一种摘要?还是签名?还是哈希值?还是其他的什么?
可以这样来理解:
HMAC 值本质上是一种"带密钥的哈希值"或"加密的摘要",其目的是为了"签名认证"。
把它拆解开来就非常清晰了:
-
它是一种(哈希值/摘要)
- 它的形态 和普通的哈希值(如 SHA256)一样,是一段固定长度的、看起来是乱码的字符串。它确实是通过哈希函数计算出来的,具备哈希的核心特性:只要输入(消息或密钥)有丝毫改变,输出的 HMAC 值就会完全不同。
-
但它不是普通的哈希值,而是"带密钥的"
- 普通的哈希值(例如 MD5、SHA1)是公开的,任何人用同一个算法对同一消息计算,得到的结果都相同。这意味着别人可以篡改消息后重新计算哈希值,让你无法察觉。
- HMAC 的核心在于引入了"密钥" 。没有这个密钥,就无法计算出相同的哈希结果。这使它从一种简单的完整性校验 (检查数据是否出错)工具,升级为一种认证(Authentication)工具(确认数据来自谁且未被篡改)。
-
它的作用是"签名认证",但不是数字签名
- 目的类似签名:HMAC 用于证明消息的来源(拥有密钥的人)和完整性。从这个目的上看,它扮演了"签名"的角色,常被称为"消息认证码"。
- 但技术上是两回事 :真正的数字签名 (如 RSA 签名)基于非对称加密(公钥/私钥),不需要共享密钥,还能提供不可否认性(用私钥签名后,拥有公钥的人都可以验证,但无法否认这个签名是自己做的)。
- HMAC 基于对称加密 (共享密钥),双方共享同一个密钥。接收方可以伪造出一个有效的 HMAC,因此无法提供不可否认性(因为双方都能计算出同样的 HMAC,无法确定到底是哪一方生成的)。
总结与类比
特性 | 普通哈希值 (e.g., SHA256) | HMAC | 数字签名 (e.g., RSA) |
---|---|---|---|
核心目的 | 完整性检查 | 完整性 + 身份认证 | 完整性 + 身份认证 + 不可否认性 |
密钥 | 无 | 对称密钥(一个秘密,双方共享) | 非对称密钥(私钥签名,公钥验证) |
输出 | 哈希值/摘要 | 带密钥的哈希值(消息认证码) | 数字签名 |
类比 | 文件封条(检查是否被拆) | 蜡封+私章(确认是谁封的) | 公证处的签名盖章(具有法律效力,无法抵赖) |
所以,最准确的描述是:HMAC 值是一个用于认证目的的消息认证码,其技术实现形式是一个带密钥的哈希值。
补充:签名和摘要的区别
摘要是对消息本身计算出的、用于验证完整性的唯一指纹
签名则是使用非对称加密中的私钥对摘要进行加密后的结果,它在验证完整性的基础上,额外提供了身份认证和不可否认性。因为我如果能用你的公钥对消息解密成功,那我就可以确定你是发送方,而不是第三方,这就是不可否认性!!
最后
回到开头的问题:啥是 HMAC?
HMAC(基于哈希的消息认证码)是一种使用加密哈希函数(如 SHA-256)和共享密钥,为消息生成一段固定长度认证码的技术。
它用来同时验证数据的完整性(未被篡改)和真实性(来自拥有正确密钥的发送方)。
接收方使用相同密钥和算法重新计算认证码并进行比对,任何不一致都意味着消息无效。