第3章:Join过程安全:OTAA与ABP入网流程、Join-Request/Join-Accept消息加密
好,咱们今天聊聊LoRaWAN入网这件事。说白了,就是设备怎么跟网络服务器“对上暗号”。
我个人习惯把入网方式分成两种:一种是每次上线都重新“握手”的OTAA,另一种是出厂就写好“通行证”的ABP。这两种方式的安全等级,说实话,差得挺远。
3.1 OTAA:动态入网,安全首选
OTAA的全称是Over-The-Air Activation。我建议你在条件允许的情况下,优先用这个方式。为什么?因为它每次入网都会生成新的会话密钥。
流程其实不复杂,就三步:
- 终端设备发送Join-Request
- 网络服务器验证后回复Join-Accept
- 双方派生会话密钥,开始通信
嗯,这里要注意一个细节:Join-Request消息本身是不加密的。你可能会问:“那安全怎么保证?”别急,往下看。
3.1.1 Join-Request消息结构
Join-Request里包含四个字段:
| 字段 | 长度 | 说明 |
|---|---|---|
| AppEUI | 8字节 | 应用标识符,相当于应用ID |
| DevEUI | 8字节 | 设备标识符,全球唯一 |
| DevNonce | 2字节 | 随机数,防重放攻击的关键 |
| MIC | 4字节 | 消息完整性校验码 |
DevNonce这个字段,我在项目里吃过亏。有一次客户反馈设备老是入网失败,查了半天发现是DevNonce重复了。原来他们用的随机数生成器质量太差,2字节的随机数居然在短时间内重复了。
3.1.2 Join-Accept消息加密
Join-Accept是网络服务器对设备的回应。这条消息是加密的,用的密钥是AppKey。AppKey是设备出厂时预置的,只有设备和网络服务器知道。
加密过程是这样的:
- 使用AES-128解密算法(你没看错,是解密算法)
- 密钥:AppKey
- 明文内容:AppNonce + NetID + DevAddr + DLSettings + RxDelay + CFList
为什么加密用解密算法?这是LoRaWAN设计上的一个“小聪明”。因为Join-Accept是服务器发给设备的,设备端用AppKey做AES解密就能得到明文。而攻击者没有AppKey,就算截获了也解不开。
3.2 ABP:静态入网,方便但有风险
ABP(Activation By Personalization)就简单多了。设备出厂时,直接把会话密钥写死在固件里。每次上电就能直接发数据,不需要入网流程。
听起来很方便对吧?但代价是安全性的下降。
3.2.1 ABP的安全隐患
我总结了一下,ABP主要有三个问题:
- 密钥泄露风险:会话密钥存储在设备中,一旦被读取,整个网络都受影响
- 重放攻击:没有DevNonce机制,攻击者可以重放旧消息
- 密钥更新困难:要换密钥?得重新烧录固件
说实话,我在实际项目中很少用ABP。除非是那种对安全性要求不高、设备数量又特别大的场景,比如简单的温湿度监测。
3.3 会话密钥派生机制
不管是OTAA还是ABP,最终都要生成两个会话密钥:
- NwkSKey:网络会话密钥,用于MAC层加密和完整性校验
- AppSKey:应用会话密钥,用于应用层数据加密
OTAA方式下,这两个密钥是这样派生的:
NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad16)
AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad16)
你看,区别就在第一个字节:0x01和0x02。这样设计的好处是,即使一个密钥被破解,另一个还是安全的。
3.4 两种入网方式对比
| 对比项 | OTAA | ABP |
|---|---|---|
| 入网流程 | 需要Join-Request/Accept | 直接通信 |
| 密钥生成 | 每次入网动态生成 | 出厂固定 |
| 防重放 | 有DevNonce机制 | 无 |
| 密钥更新 | 重新入网即可 | 需重新烧录 |
| 适用场景 | 大多数场景 | 低安全需求、大规模部署 |
我个人建议,除非有特殊原因,否则都用OTAA。虽然入网过程多花几秒钟,但换来的是更高的安全性。
3.5 核心流程可视化
下面这张图展示了OTAA入网的完整流程,包括消息交换和密钥派生过程:
从这张图可以清楚看到,整个入网过程的核心就是“先验证身份,再派生密钥”。设备用AppKey证明自己是合法的,服务器才放心地把会话密钥交出来。
3.6 实际部署建议
最后,分享几个我在实际项目中的经验:
- DevNonce管理:确保每次入网都生成不同的随机数,建议用硬件随机数发生器
- AppKey存储:如果设备支持安全元件(SE),一定要把AppKey存进去
- 入网失败处理:设备入网失败后,建议等待随机时间再重试,避免“雪崩效应”
- ABP慎用:除非你确定攻击者无法物理接触设备,否则别用ABP
嗯,关于入网安全,今天就聊这么多。记住一句话:入网是安全的第一道门,门没锁好,后面做再多加密都是白搭。