消息认证码(MAC)是验证数据完整性与来源真实性的机制,使用共享密钥生成固定长度标签,通过比对标签判断是否被篡改或来源不可信;Sodium 提供 sodium_crypto_auth(仅认证)和 AEAD(如 xchacha20poly1305,加密+认证一体化)两种方式,推荐优先使用 AEAD。

什么是消息认证码(MAC)
消息认证码不是加密,而是验证数据完整性和来源真实性的机制。它用一个共享密钥对明文生成固定长度的标签(tag),接收方用同一密钥重新计算并比对——不一致就说明数据被篡改或来源不可信。Sodium 提供了两种主流方式:对称认证(sodium_crypto_auth)和带认证的加密(AEAD,如 sodium_crypto_aead_xchacha20poly1305_ietf_encrypt)。
用 sodium_crypto_auth 实现轻量级 MAC
适合只需要校验、无需加密的场景,比如 API 请求签名、配置项防修改。
- 调用 sodium_crypto_auth() 生成认证标签,传入明文和 32 字节密钥
- 把原文和 tag 一起传输或存储(tag 本身不敏感,但密钥必须保密)
- 验证时用 sodium_crypto_auth_verify() 比对,返回 true 才可信
- 注意:该函数不做加密,明文仍是可见的;若需保密,应搭配 AEAD 或先加密再认证
首选方案:用 AEAD 模式一步到位
现代应用强烈推荐使用认证加密(AEAD),它在加密同时生成认证标签,天然防重放、防篡改、防填充攻击。
- sodium_crypto_aead_xchacha20poly1305_ietf_encrypt() 是当前最优选:支持长 nonce、抗侧信道、性能好、兼容性强
- 加密输出包含密文 + 16 字节认证标签(自动附加),解密前会先验证 tag,失败直接返回 false
- nonce 必须唯一,建议每次加密都用 random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES)
- 密钥需长期稳定,可用 sodium_crypto_aead_xchacha20poly1305_ietf_keygen() 生成一次并安全保存
关键注意事项
即使函数封装友好,踩坑点仍集中在这几个地方:
立即学习“PHP免费学习笔记(深入)”;
- 不要复用 nonce:相同 key + 相同 nonce 加密不同消息会导致密钥泄露
- 不要忽略验证返回值:解密函数失败时一定返回 false,必须显式判断,不能假设成功
- 密钥不能硬编码:应通过环境变量、密钥管理服务(KMS)或加密配置文件加载
- 避免混用模式:比如用 IETF 版本加密,却用非 IETF 版本解密,会因 nonce 长度或格式不匹配而失败



















