1. CCM模式概述
各位同学,咱们开始第一讲。AES CCM 这个模式,说实话,刚入行的人容易把它跟 GCM 搞混。我当年也踩过这个坑——项目做到一半才发现选错了模式,改起来那叫一个痛苦。
CCM 全称是 Counter with CBC-MAC。名字挺长,但拆开看就清楚了:
- Counter:计数器模式,负责加密
- CBC-MAC:CBC 模式的 MAC,负责认证
说白了,CCM 就是把加密和认证拼在一起。先算 MAC,再加密。嗯,这个顺序很重要,后面我会细说。
核心定义:CCM 是一种认证加密(AEAD)模式。它同时提供机密性和完整性保护。你发给对方的数据,别人看不懂,也改不了。
为什么需要 CCM?
你想想看,早期很多协议只用 AES 加密。加密能防偷看,但防不了篡改。攻击者可以翻转几个比特,接收方根本不知道数据被改过。
我在做物联网项目时遇到过这种情况:设备上报的温度数据被中间人篡改,服务器收到的是假数据,但解密后看起来完全合法。嗯,这就是没有认证的后果。
CCM 就是为了解决这个问题。它把加密和认证绑在一起,一次性搞定。你不需要自己拼凑加密 + HMAC,也不用担心拼错了出安全漏洞。
哪些地方在用 CCM?
- Wi-Fi 安全:WPA2 协议里就用 CCM(叫 CCMP)
- ZigBee:智能家居设备通信
- 蓝牙:低功耗蓝牙的安全层
- IEEE 802.15.4:无线传感器网络
这些场景有个共同点:资源受限。设备算力弱,内存小,CCM 正好适合——它只需要 AES 加密引擎,不需要额外硬件。
CCM 与 GCM 的区别
这是面试常考题,也是项目选型的关键。我直接给你一张对比表,一目了然:
| 对比维度 | CCM | GCM |
|---|---|---|
| 加密方式 | CTR 模式 | CTR 模式 |
| 认证方式 | CBC-MAC | GHASH(多项式乘法) |
| 处理顺序 | 先认证,后加密 | 先加密,后认证 |
| 并行性 | 不支持(MAC 是串行的) | 支持(GHASH 可流水线) |
| 硬件加速 | 只需要 AES 核心 | 需要 AES + 乘法器 |
| Nonce 长度 | 7~13 字节(固定) | 12 字节(推荐) |
| 性能 | 慢(串行瓶颈) | 快(可并行) |
| 标准化 | RFC 3610 | NIST SP 800-38D |
我个人的经验是:
- 如果你在做嵌入式、物联网、低功耗设备,选 CCM。它只需要 AES 硬件,很多 MCU 自带 AES 引擎,跑 CCM 几乎零成本。
- 如果你在做服务器、网关、高性能场景,选 GCM。现代 CPU 有 AES-NI 和 PCLMULQDQ 指令,GCM 能跑到几十 Gbps。
避坑指南:我曾经见过一个项目,在 ARM Cortex-M0 上硬跑 GCM。没有乘法器,GHASH 全靠软件模拟,结果加密 1KB 数据要花 50 毫秒。后来换成 CCM,同样的硬件,速度提升了 3 倍。选型一定要看硬件能力。
CCM 的工作流程
我画了一张流程图,帮你理解 CCM 到底怎么干活:
流程其实不复杂:
- 格式化:把 Nonce、明文长度等信息拼成 B0 块
- CBC-MAC:用 CBC 模式跑一遍明文和附加数据,得到 MAC
- 生成标签:取 MAC 的前 M 字节(M 是你要的认证码长度)
- CTR 加密:用 CTR 模式加密明文,同时加密 MAC 标签
个人技巧:我习惯在实现时把 Nonce 和计数器分开管理。Nonce 每次加密必须不同,计数器从 0 开始。如果 Nonce 重复了,CTR 模式的密钥流就会重复,加密就废了。嗯,这个坑我踩过,后面章节会专门讲。
CCM 的参数配置
CCM 有几个参数需要你提前定好:
| 参数 | 可选值 | 说明 |
|---|---|---|
| M(MAC 长度) | 4, 6, 8, 10, 12, 14, 16 字节 | 推荐 8 或 16。4 太短,容易被暴力 |
| L(长度域) | 2~8 字节 | 决定最大消息长度。L=2 时最大 2^16 字节 |
| Nonce 长度 | 15 - L 字节 | L=2 时 Nonce 13 字节;L=8 时 Nonce 7 字节 |
这里有个权衡:L 越大,能加密的消息越长,但 Nonce 越短,重复概率越高。我一般选 L=2,Nonce 13 字节。除非你要加密超大数据包,否则 64KB 的消息长度够用了。
避坑指南:我曾经见过有人把 L 设成 8,Nonce 只剩 7 字节。结果设备多了,Nonce 频繁重复,加密直接失效。Nonce 管理是 CCM 最容易被忽视的环节,后面我会专门开一章讲。
CCM 的局限性
说实话,CCM 不是完美的。它有几个硬伤:
- 不能并行:CBC-MAC 是串行的,必须等前一块算完才能算下一块。大文件加密时性能很差。
- 不支持增量认证:如果你只改了数据的一小部分,MAC 必须全部重算。GCM 的 GHASH 可以增量更新,CCM 不行。
- Nonce 敏感:Nonce 重复直接导致安全崩溃。CTR 模式下,重复 Nonce 意味着密钥流相同,异或一下就能恢复明文。
- 实现复杂:格式化 B0 块、处理附加数据、对齐边界……这些细节容易出错。我见过好几个开源实现都有 bug。
但话说回来,在资源受限的场景下,CCM 仍然是首选。它只需要 AES 加密,不需要额外的乘法器或哈希函数。很多 8 位 MCU 都能跑。
总结:CCM 是 AES 认证加密模式中的「老黄牛」。它不花哨,但可靠。选它之前,先确认你的场景:资源受限、消息长度不大、Nonce 可控。如果这些条件都满足,CCM 不会让你失望。