目录
消息验证码(MAC)也可以称为消息认证码。
定义:
消息验证码(Message Authentication Code, MAC)是一种用于验证消息完整性 和真实性的密码学工具。
MAC 无法证明消息来源的唯一性(与数字签名不同)。
那么如何做到的呢?
消息认证码的输入包括任意长度的消息和一个发送者与接收者之间的共享密钥。输出固定长度的数据,输出的数据就是 MAC 值。
消息认证码和单向散列函数的区别 就在有没有这个共享密钥。消息认证码就是利用共享密钥进行认证的。

MAC 的工作原理、MAC 的生成和验证流程如下:
-
生成 MAC(发送方)
- 输入:原始消息(Message) + 共享密钥(Secret Key)。
- 计算 MAC:通过特定算法(如 HMAC)生成固定长度的标签(MAC Tag)。
- 发送:将原始消息和 MAC Tag 一起发送给接收方。
-
验证 MAC(接收方)
- 接收数据:获取消息和 MAC Tag。
- 重新计算 MAC:使用相同的密钥和算法对消息重新生成 MAC Tag。
- 比对:
- 一致:消息未被篡改,且由合法发送方生成。
- 不一致:消息可能被篡改,或密钥错误。
认证流程

MAC 的分类
-
基于哈希的 MAC(HMAC)
- 原理:结合哈希函数(如 SHA-256)和密钥生成 MAC。
- 特点:高效、标准化(RFC 2104),广泛用于 TLS、JWT 等协议。
-
基于分组密码的 MAC(如 CMAC)
- 原理:使用分组密码算法(如 AES)生成 MAC。
- 特点:适合硬件实现,资源受限场景常用。
-
其他类型
- Poly1305:基于模运算的高效 MAC,与 ChaCha20 加密算法配合使用。
- GMAC:基于伽罗华域的 MAC,用于 GCM 加密模式。
认证加密
什么是认证加密?
2000 年以后,人们基于认证 的研究更加进一步,产生了认证加密 (AE :Authenticated Encryption,AEAD :Authenticated Encryption with Associated Data)。
认证加密 是一种将对称密码和消息认证相结合的技术,同时满足加密性 ,完整性 和认证性三大功能。
为什么需要认证加密?
传统的数据保护方案通常将加密和完整性验证分开处理(例如先加密数据,再单独计算MAC),但这种分离可能引入安全漏洞:
- 加密不验证完整性:攻击者可篡改密文,导致解密后得到无意义但看似合法的数据(如填充错误)。
- 组合方式错误:若加密与MAC的组合顺序不当(如先MAC后加密),可能遭受选择密文攻击(CCA)。
- 效率低下:分开实现加密和MAC需要两次计算,增加延迟和资源消耗。
认证加密(AE/ AEAD) 通过将加密和认证原子化整合,从根本上杜绝了上述问题。
认证加密的种类:
-
例如 Encrypt-then-MAC,先用对称密码将明文加密,然后计算密文的 MAC 值。Encrypt-and-MAC,将明文用对称密码加密,并对明文计算 MAC 值。
-
MAC-then-Encrypt,先计算明文的 MAC 值,然后将明文和 MAC 值同时用对称密码加密。(在 HTTPS 中,一般使用 MAC-then-Encrypt 这种模式进行处理。)
-
GCM(Galois/Counter Mode)是一种认证加密方式。GCM 中使用 AES 等 128 位比特分组密码的 CTR 模式,并使用一个反复进行加法和乘法运算的散列函数来计算 MAC 值。CTR 模式加密与 MAC 值的计算使用的是相同密钥,所以密钥管理很方便。专门用于消息认证码的 GCM 成为 GMAC。GCM 和 CCM (CBC Counter Mode) 都是被推荐的认证加密方式。
MAC的攻击手段
重发攻击
窃听者不直接破解消息认证码,而是把它保存起来,反复利用 ,这种攻击就叫做重放攻击(replay attack)。
防止重放攻击可以有 3 种方法:
-
序号 :
每条消息都增加一个递增的序号,并且在计算 MAC 值的时候把序号也包含在消息中。这样攻击者如果不破解消息认证码就无法计算出正确的 MAC 值。这个方法的弊端是每条消息都需要多记录最后一个消息的序号。
-
时间戳 :
发送消息的时候包含当前时间,如果收到的时间与当前的不符,即便 MAC 值正确也认为是错误消息直接丢弃。这样也可以防御重放攻击。这个方法的弊端是,发送方和接收方的时钟必须一致,考虑到消息的延迟,所以需要在时间上留下一定的缓冲余地。这个缓冲之间还是会造成重放攻击的可趁之机。
-
nonce :
在通信之前,接收者先向发送者发送一个一次性的随机数 nonce。发送者在消息中包含这个 nonce 并计算 MAC 值。由于每次 nonce 都会变化,因此无法进行重放攻击。这个方法的缺点会导致通信的数据量增加。
密钥推测攻击
在消息认证码(MAC)中,密钥推测攻击(Key Guessing Attack) 是一种针对 MAC 密钥的暴力破解攻击。攻击者通过已知的明文-标签对(Message-Tag Pair),尝试猜测生成 MAC 的密钥,从而伪造合法标签,破坏 MAC 的安全性。
密钥推测攻击的原理
-
攻击目标:
通过已知的明文 ( M ) 和对应的 MAC 标签 ( T ),逆向推导出生成 ( T ) 的密钥 ( K )。
公式: ( T = \\text{MAC}(K, M) \\rightarrow \\text{求 } K ) 。
-
攻击方式:
- 暴力穷举:尝试所有可能的密钥 ( K' ),计算 ( \\text{MAC}(K', M) ) ,直到 ( \\text{MAC}(K', M) = T ) 。
- 字典攻击:使用预生成的常用密钥字典(如弱密码库),加速猜测过程。
-
攻击前提:
- 攻击者至少掌握一个有效的明文-标签对 ( (M, T) )。
- MAC 算法的密钥空间较小(如密钥长度过短)。
密钥推测攻击的核心威胁在于弱密钥 或短密钥的脆弱性。
消息认证码无法解决的问题
消息认证码虽然可以证明双方发送的消息是一致的,没有篡改,也不存在中间人伪装。但是它无法 "对第三方证明 " 和 "防止抵赖"。
-
无法 "对第三方证明" 原因是因为消息认证码中用到的密钥是共享密钥,通信双方都有这个密钥,所以对第三方无法证明消息到底出自双方中的哪一方。(解决 "第三方证明" 的问题需要用到数字签名)
-
无法 "防止抵赖" 原因是也是因为消息认证码的共享密钥双方都有,无法判断消息是发自于哪一方。所以消息认证码无法防止否认(nonrepudiation)。(解决 "防止抵赖" 的问题需要用到数字签名)