4. 数据帧加密与完整性保护:FRMPayload加密、MIC计算与帧计数器机制

这一章,我们聊聊LoRaWAN安全里最核心的三个动作——加密、完整性校验和防重放。说白了,就是保证你的数据在空中飞的时候,别人看不懂、改不了、也拿旧数据来骗你。

我刚开始接触LoRaWAN时,总觉得这三件事是分开的。后来踩了坑才明白,它们其实是拧在一起的一条链。任何一个环节出问题,整条链路就断了。

4.1 FRMPayload加密:AES-128-CTR模式

先讲加密。LoRaWAN对数据载荷(FRMPayload)用的是AES-128-CTR模式。CTR模式,说白了就是“流加密”。它不像CBC那样需要把数据切成块再一块块加密,而是先生成一个密钥流,然后跟明文做异或。

为什么选CTR?我个人觉得,主要是两个原因:一是它支持并行计算,效率高;二是它不需要填充,数据长度不变。这在物联网场景里很实用——你想想看,一个传感器报文可能就十几个字节,要是因为填充多出几个字节,反而浪费了宝贵的空中时间。

CTR模式的关键,在于“计数器”的构造。LoRaWAN里,这个计数器由以下几个部分组成:

  • 方向位(Dir):0表示上行,1表示下行
  • DevAddr:设备地址,32位
  • 帧计数器(FCnt):32位,上行和下行分开
  • 块计数器(Block Counter):从0开始,每加密16字节加1

这些参数拼在一起,形成一个16字节的输入块,送入AES-128引擎,生成密钥流。然后跟明文做异或,得到密文。

核心公式:

加密:Ciphertext = Plaintext ⊕ AES_128(AppSKey, CounterBlock)

解密:Plaintext = Ciphertext ⊕ AES_128(AppSKey, CounterBlock)

注意,加密和解密用的是同一个操作——异或。所以CTR模式天然支持对称加解密。

我在项目中遇到过一个问题:有人把上行和下行的帧计数器混用了。结果解密出来的数据全是乱码。嗯,这里要注意——上行和下行必须使用各自的FCnt,不能共用。

4.2 MIC计算:AES-128-CMAC

加密保证的是机密性,但还不够。你还需要保证数据没有被篡改。这就是MIC(消息完整性校验码)的作用。

LoRaWAN用的是AES-128-CMAC算法。CMAC,全称是Cipher-based Message Authentication Code。它跟普通的哈希不一样——它需要密钥,而且输出是固定的128位,但LoRaWAN只取前32位(4字节)作为MIC。

MIC的计算范围,是整个MAC层载荷(MHDR + FHDR + FPort + FRMPayload)。注意,FRMPayload是密文,不是明文。所以MIC是在加密之后计算的。

计算流程大致是这样的:

  1. 把整个MAC层载荷拼接成一个数据块
  2. 用NwkSKey(网络会话密钥)作为CMAC的密钥
  3. 运行AES-128-CMAC算法,得到128位输出
  4. 取前32位,作为MIC

一个小技巧:

我曾经调试一个设备,发现MIC总是校验失败。查了半天,原来是FRMPayload为空时,MIC的计算方式有变化。空载荷时,FRMPayload长度为0,但MIC仍然要计算。很多新手会忽略这个边界情况。

MIC的验证是在接收端完成的。如果接收端重新计算的MIC跟收到的MIC不一致,说明数据在传输过程中被篡改了,直接丢弃。

4.3 帧计数器机制

帧计数器(FCnt)是LoRaWAN安全里最容易出问题的地方,也是我排查故障时最先检查的项目之一。

FCnt的作用,说白了就是防重放攻击。每个设备维护两个计数器:

  • FCntUp:上行帧计数器,每发送一帧加1
  • FCntDown:下行帧计数器,每接收一帧加1

网络服务器也会维护对应的计数器。每次收到一帧,服务器会检查FCnt是否大于上一次的值。如果小于或等于,就认为是重放攻击,直接丢弃。

场景 FCnt行为 常见问题
正常通信 FCntUp递增,FCntDown递增 无
设备重启 FCntUp可能重置为0 服务器可能拒绝,需要ABP设备手动同步
网络切换 FCnt可能跳跃 服务器需要支持FCnt跳跃容忍
重放攻击 FCnt重复或回退 服务器直接丢弃

警告:

ABP(Activation By Personalization)模式下,设备重启后FCnt会重置为0。如果服务器没有做特殊处理,会认为这是重放攻击。我曾经见过一个项目,设备每次断电重启后都无法通信,就是因为FCnt回退被服务器拒绝了。

解决方案:要么在服务器端开启FCnt跳跃容忍,要么在设备端把FCnt写入非易失性存储。

4.4 三者之间的关系

加密、MIC、FCnt,这三者不是孤立的。它们共同构成了LoRaWAN的安全防线。我画了一张图,帮你理清它们的关系:

数据帧安全处理流程 原始FRMPayload 步骤1:AES-128-CTR加密 使用AppSKey + 计数器块 加密后的FRMPayload 步骤2:AES-128-CMAC计算MIC 使用NwkSKey + 整个MAC载荷 步骤3:组装完整数据帧 MHDR + FHDR(含FCnt) + FRMPayload(密文) + MIC FCnt参与加密计数器构造 也参与MIC计算

从这张图你可以看到,FCnt不仅用于防重放,还参与了加密计数器的构造和MIC的计算。所以FCnt一旦出错,加密和完整性校验都会跟着出问题。

4.5 常见故障排查清单

最后,我整理了一份排查清单。你在现场遇到问题时,可以按这个顺序检查:

  1. 检查FCnt是否连续:设备端和服务器端的FCnt是否一致?有没有回退?
  2. 检查密钥是否正确:AppSKey和NwkSKey是否匹配?ABP设备经常因为密钥写错导致解密失败。
  3. 检查MIC计算范围:是不是把FRMPayload的明文当成了密文来计算?
  4. 检查空载荷情况:FRMPayload为空时,MIC计算有没有特殊处理?
  5. 检查方向位:上行和下行的计数器构造是否用了正确的Dir值?

我的经验:

我曾经调试一个网关,发现所有上行数据都能解密,但下行数据全是乱码。查了两天,最后发现是服务器端把下行帧的Dir位设成了0(上行)。就这么一个比特的错误,导致整个下行链路瘫痪。所以,排查时别放过任何一个细节。

好了,这一章的内容就到这里。加密、MIC、FCnt,这三者你只要理解了它们各自的作用和相互依赖关系,LoRaWAN安全架构的骨架就算搭起来了。