3. LoRaWAN 密钥体系:七把钥匙,一把都不能少
说实话,我刚接触 LoRaWAN 的时候,被这一堆 Key 搞得有点晕。
AppKey、NwkKey、AppSKey、NwkSKey…… 还有 FNwkSIntKey、SNwkSIntKey、NwkSEncKey。
七个名字,七个不同的用途。弄混一个,设备就入不了网,或者数据被截了你也发现不了。
这一节,我就带你把这七把钥匙彻底理清楚。
你想想看,一个 LoRaWAN 设备从出厂到正常工作,密钥体系其实就分两大阶段:
激活前 和 激活后。
核心原则:LoRaWAN 1.0.x 和 1.1 的密钥体系有差异。1.1 版本把网络层和应用层彻底分离,密钥数量从 3 个变成了 7 个。我们以 LoRaWAN 1.1 为准来讲,这是目前的主流。
3.1 根密钥:AppKey 与 NwkKey
这两个是「根密钥」,写在设备出厂固件里。
我个人习惯把它们比作「身份证的底档」—— 一旦泄露,整个设备就废了。
- AppKey(Application Key):应用层根密钥。用于派生应用会话密钥 AppSKey。
- NwkKey(Network Key):网络层根密钥。用于派生所有网络层会话密钥。
在 LoRaWAN 1.0.x 时代,只有一个根密钥叫 AppKey,既派网络密钥又派应用密钥。
到了 1.1,LoRaWAN 联盟觉得这样不安全 —— 万一网络层被攻破,应用数据也一起完蛋。
所以拆成了两个。嗯,这里要注意:AppKey 和 NwkKey 永远不能在空中传输。
我曾经见过一个项目,厂商为了方便,把 AppKey 通过串口明文打印出来。结果测试阶段就被同事拍照传到了群里…… 那批模块最后全部报废重烧。根密钥的保管,再怎么小心都不为过。
3.2 会话密钥:OTAA 激活后动态生成
设备通过 OTAA(Over-The-Air Activation)入网时,服务器和终端会基于根密钥,结合随机数协商出一组临时密钥。
这组密钥只在当前会话有效,设备重启或重新入网就会变。
会话密钥一共 5 个,分两类:
3.2.1 网络层会话密钥(3 个)
| 密钥名称 | 全称 | 用途 |
|---|---|---|
| FNwkSIntKey | Forwarding Network Session Integrity Key | 上行数据完整性校验(网络服务器转发用) |
| SNwkSIntKey | Serving Network Session Integrity Key | 下行数据完整性校验(服务网络服务器用) |
| NwkSEncKey | Network Session Encryption Key | 网络层 MAC 命令加密 |
为什么网络层要拆成三个?
说白了,是为了「职责分离」。
FNwkSIntKey 负责上行完整性,SNwkSIntKey 负责下行完整性,NwkSEncKey 负责加密 MAC 命令。
这样即使某个网络服务器被攻破,它也只能伪造上行数据,伪造不了下行指令。
我自己的经验:调试时如果发现设备能入网但收不到下行,先检查 SNwkSIntKey 是否匹配。我曾经花了两天排查射频问题,最后发现是服务器和终端算出来的 SNwkSIntKey 不一样 —— 因为 Join-Response 的 MIC 计算用错了密钥。
3.2.2 应用层会话密钥(1 个)
- AppSKey(Application Session Key):用于加密应用层负载数据。也就是你传感器上传的温度、湿度这些业务数据。
AppSKey 只由 AppKey 派生,网络服务器拿不到。
这意味着:网络层只能看到加密后的密文,解不开你的业务数据。
嗯,这才是真正的端到端加密。
3.2.3 遗留密钥:NwkSKey(仅 1.0.x)
如果你还在维护 LoRaWAN 1.0.x 的老设备,会看到一个叫 NwkSKey 的密钥。
它同时承担了网络层加密、完整性校验和应用层加密 —— 一个密钥干三份活。
我个人建议:新项目一律用 1.1,别再用 NwkSKey 了。
3.3 密钥派生流程(OTAA)
我画了一张图,把整个派生关系串起来。你看完应该就全通了。
3.4 密钥使用场景速查
我把每个密钥在数据帧里的使用场景整理了一下。调试的时候对照着看,能省不少时间。
| 数据帧类型 | 加密密钥 | 完整性校验密钥 |
|---|---|---|
| 上行应用数据(FRMPayload) | AppSKey | SNwkSIntKey |
| 下行应用数据(FRMPayload) | AppSKey | SNwkSIntKey |
| 上行 MAC 命令(FRMPayload) | NwkSEncKey | FNwkSIntKey |
| 下行 MAC 命令(FRMPayload) | NwkSEncKey | SNwkSIntKey |
| FOptLen 中的 MAC 命令 | 不加密 | FNwkSIntKey / SNwkSIntKey |
一个小技巧:如果你用 Wireshark 抓 LoRaWAN 包,发现 MIC 校验失败,先确认你填的密钥对不对。
上行 MIC 用的是 FNwkSIntKey,下行用的是 SNwkSIntKey —— 我见过有人把这两个搞反,排查了一下午。
3.5 避坑指南:密钥管理常见问题
- 根密钥硬编码风险:AppKey 和 NwkKey 写在固件里,如果固件被逆向,所有设备都暴露。建议结合芯片唯一 ID 做密钥分散。
- 会话密钥未及时更新:设备长时间在线,会话密钥不变。如果怀疑被窃,应该触发重新入网(发送 LinkCheckReq 或强制重启)。
- 1.0.x 与 1.1 混用:服务器配置成 1.1,终端用 1.0.x 的固件,密钥派生会完全错位。我遇到过最离谱的一次,设备能入网但发不了数据,最后发现是 NwkSKey 和 NwkSEncKey 长度不同。
- 密钥存储位置:生产环境下,根密钥建议放在安全元件(SE)或 TEE 里。别图省事放 Flash 明文区。
我曾经帮一个客户排查产线问题,发现 30% 的设备入网失败。最后定位到:烧录工位把 AppKey 和 NwkKey 写反了。两个密钥长度一样,但内容不同,导致 Join-Accept 解密失败。从那以后,我要求所有产线烧录脚本必须加 CRC 校验和回读验证。
3.6 小结
七把钥匙,其实就两类:
根密钥(AppKey、NwkKey)—— 出厂烧录,永不泄露。
会话密钥(FNwkSIntKey、SNwkSIntKey、NwkSEncKey、AppSKey)—— 入网协商,动态更新。
还有一个 NwkSKey,是 1.0.x 的历史遗留,新项目别碰。
记住一句话:根密钥管身份,会话密钥管通信。
搞清楚了这七把钥匙的关系,LoRaWAN 安全体系你就掌握了 80%。