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 到底怎么干活:

CCM 加密与认证流程 输入数据 明文 (P) 附加数据 (A) Nonce (N) 密钥 (K) 步骤 1 格式化 B0 块 步骤 2 CBC-MAC 计算 步骤 3 生成 MAC 标签 步骤 4 CTR 模式加密 输出 密文 + MAC 关键点 • 先算 MAC,再加密 • MAC 计算覆盖明文 + 附加数据 • 加密时 MAC 也被加密(防伪造) Nonce 构造 • 标志字节 + Nonce + 消息长度 • Nonce 必须唯一,不能重复

流程其实不复杂:

  1. 格式化:把 Nonce、明文长度等信息拼成 B0 块
  2. CBC-MAC:用 CBC 模式跑一遍明文和附加数据,得到 MAC
  3. 生成标签:取 MAC 的前 M 字节(M 是你要的认证码长度)
  4. 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 不会让你失望。