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是在加密之后计算的。
计算流程大致是这样的:
- 把整个MAC层载荷拼接成一个数据块
- 用NwkSKey(网络会话密钥)作为CMAC的密钥
- 运行AES-128-CMAC算法,得到128位输出
- 取前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的安全防线。我画了一张图,帮你理清它们的关系:
从这张图你可以看到,FCnt不仅用于防重放,还参与了加密计数器的构造和MIC的计算。所以FCnt一旦出错,加密和完整性校验都会跟着出问题。
4.5 常见故障排查清单
最后,我整理了一份排查清单。你在现场遇到问题时,可以按这个顺序检查:
- 检查FCnt是否连续:设备端和服务器端的FCnt是否一致?有没有回退?
- 检查密钥是否正确:AppSKey和NwkSKey是否匹配?ABP设备经常因为密钥写错导致解密失败。
- 检查MIC计算范围:是不是把FRMPayload的明文当成了密文来计算?
- 检查空载荷情况:FRMPayload为空时,MIC计算有没有特殊处理?
- 检查方向位:上行和下行的计数器构造是否用了正确的Dir值?
我的经验:
我曾经调试一个网关,发现所有上行数据都能解密,但下行数据全是乱码。查了两天,最后发现是服务器端把下行帧的Dir位设成了0(上行)。就这么一个比特的错误,导致整个下行链路瘫痪。所以,排查时别放过任何一个细节。
好了,这一章的内容就到这里。加密、MIC、FCnt,这三者你只要理解了它们各自的作用和相互依赖关系,LoRaWAN安全架构的骨架就算搭起来了。