2、LoRaWAN密钥体系:根密钥AppKey与NwkKey、会话密钥AppSKey与NwkSKey、密钥层级与派生关系
聊LoRaWAN安全,绕不开的就是这套密钥体系。说实话,我第一次接触LoRaWAN 1.0.x版本时,被那一堆Key搞得有点晕——AppKey、NwkKey、AppSKey、NwkSKey,还有后来的JSKey、FNwkSIntKey……名字长得像,功能却完全不同。今天咱们就把这锅粥理清楚。
2.1 根密钥:设备出厂时的“身份证”
根密钥是LoRaWAN安全体系的基石。它是在设备生产时烧录进去的,理论上这辈子都不该离开设备。我见过一些厂商为了省事,把根密钥明文写在固件里,结果被逆向工程一锅端——嗯,这属于典型的“省小钱吃大亏”。
LoRaWAN有两个版本的根密钥体系,咱们分开说:
2.1.1 LoRaWAN 1.0.x:AppKey独挑大梁
在1.0.x版本中,只有一个根密钥——AppKey。它身兼两职:
- 用于空中激活(OTAA)时的Join过程
- 用于派生后续的会话密钥
说白了,AppKey就是一把万能钥匙。设备入网时,服务器用AppKey验证设备身份;入网成功后,再用AppKey派生出AppSKey和NwkSKey。这种设计有个隐患——如果AppKey泄露,攻击者不仅能伪造设备入网,还能解密所有通信数据。
2.1.2 LoRaWAN 1.1.x:NwkKey与AppKey分权制衡
到了1.1.x版本,LoRaWAN联盟终于意识到“一把钥匙开所有锁”太危险了。于是他们把根密钥拆成了两个:
| 密钥名称 | 长度 | 用途 |
|---|---|---|
| NwkKey | 128位 | 网络层根密钥,用于Join过程、派生网络会话密钥 |
| AppKey | 128位 | 应用层根密钥,用于派生应用会话密钥 |
为什么要拆?你想想看,在1.0.x中,网络服务器和应用服务器共享同一个AppKey。如果应用服务器被攻破,网络层也跟着完蛋。1.1.x把网络层和应用层的根密钥分开——网络服务器只知道NwkKey,应用服务器只知道AppKey。这样即使应用服务器被黑,攻击者也拿不到网络层的密钥。
我在一个智慧农业项目中就吃过这个亏。当时用的是1.0.x协议栈,客户的应用服务器被挖矿病毒入侵,AppKey被窃取。结果攻击者不仅伪造了设备入网,还伪造了下行指令让灌溉系统乱喷水……后来升级到1.1.x,把NwkKey和AppKey分开存储,才算彻底解决这个问题。
2.2 会话密钥:一次会话一把锁
根密钥是“死”的,永远不变。但实际通信中,我们需要“活”的密钥——每次入网都重新生成。这就是会话密钥的由来。
2.2.1 网络会话密钥(NwkSKey / FNwkSIntKey + SNwkSIntKey + NwkSEncKey)
在1.0.x中,只有一个网络会话密钥——NwkSKey。它负责两件事:
- 验证消息完整性(MIC计算)
- 加密MAC命令(如ADR、LinkCheck等)
1.1.x又把它拆成了三个:
- FNwkSIntKey:前向网络会话完整性密钥,用于上行消息的MIC验证
- SNwkSIntKey:服务端网络会话完整性密钥,用于下行消息的MIC验证
- NwkSEncKey:网络会话加密密钥,用于加密MAC命令
为什么要拆?因为上下行消息的安全需求不同。上行消息需要防止重放攻击,下行消息需要防止伪造。分开后,每个密钥只负责一件事,攻击者更难下手。
2.2.2 应用会话密钥(AppSKey)
AppSKey是应用层的会话密钥,用于加密应用数据(比如传感器采集的温度、湿度)。它只被应用服务器和终端设备持有,网络服务器无权访问。
这里有个常见的误解:很多人以为AppSKey是端到端加密的保障。其实不然——LoRaWAN的加密是“逐跳”的,终端到网络服务器之间用NwkSKey加密,网络服务器到应用服务器之间用AppSKey加密。网络服务器虽然不能解密应用数据,但它能看到数据包的长度和发送时间。如果你对隐私要求极高,建议在应用层再做一层加密。
- NwkSKey系列:保护网络层,验证身份、加密MAC命令
- AppSKey:保护应用层,加密用户数据
2.3 密钥层级与派生关系
好了,现在咱们把根密钥和会话密钥串起来。LoRaWAN的密钥派生遵循一个清晰的层级结构:
LoRaWAN 1.0.x 密钥派生:
AppKey (根密钥)
├── 通过Join过程 → NwkSKey (网络会话密钥)
└── 通过Join过程 → AppSKey (应用会话密钥)
LoRaWAN 1.1.x 密钥派生:
NwkKey (网络根密钥)
├── 通过Join过程 → FNwkSIntKey
├── 通过Join过程 → SNwkSIntKey
└── 通过Join过程 → NwkSEncKey
AppKey (应用根密钥)
└── 通过Join过程 → AppSKey
派生过程使用的是AES-CMAC算法。具体来说,终端设备和网络服务器各自用根密钥对一串特定格式的数据做AES-CMAC计算,得到会话密钥。这串数据包含:
- JoinNonce(服务器生成的随机数)
- NetID(网络标识符)
- DevNonce(设备生成的随机数)
- 固定填充字节
为什么用AES-CMAC而不是直接加密?因为AES-CMAC是消息认证码算法,它保证派生出的密钥既依赖于根密钥,又依赖于随机数。即使攻击者知道根密钥,只要不知道JoinNonce和DevNonce,也无法计算出会话密钥。
2.4 密钥生命周期管理
聊完派生,咱们说说密钥怎么“活”和怎么“死”。
2.4.1 根密钥:终身制
根密钥在设备出厂时写入,理论上永不更改。如果根密钥泄露,设备就废了——只能返厂重新烧录。所以,根密钥的存储安全是第一位的。
2.4.2 会话密钥:每次入网刷新
设备每次通过OTAA入网,都会生成全新的会话密钥。这意味着:
- 如果设备掉线重连,之前的会话密钥立即失效
- 攻击者即使截获了某次会话的密钥,也只能解密那一次会话的数据
这就是“前向安全性”的体现——一次泄露不会影响历史数据。我建议所有LoRaWAN设备都使用OTAA方式入网,不要用ABP(激活入网)。ABP的会话密钥是写死的,一旦泄露,设备就永远不安全了。
2.5 小结
LoRaWAN的密钥体系,说白了就是一套“根密钥保底、会话密钥动态、层级隔离”的安全架构。根密钥是设备的“基因”,永远不变;会话密钥是设备的“临时身份证”,每次入网换一张。1.0.x用一把AppKey管所有,1.1.x拆成NwkKey和AppKey各管一摊——后者更安全,但也更复杂。
我个人建议,新项目直接上1.1.x协议栈。虽然密钥管理麻烦一点,但安全收益是实打实的。如果你还在维护1.0.x的老设备,至少确保AppKey的存储安全,并且定期让设备重新入网刷新会话密钥。
下一章,咱们聊聊Join过程——这些密钥到底是怎么在设备和服务器之间“握手”的。到时候你会发现,密钥派生只是开胃菜,真正的安全博弈在Join过程中才刚开始。