4. Mesh网络配置流程:Provisioning(配网)过程详解、AppKey与NetKey的生成与分发
好,咱们进入正题。Mesh网络要跑起来,第一步就是配网——也就是Provisioning。很多初学者觉得配网就是“把设备加进去”,其实没那么简单。我当年第一次调Mesh协议栈时,就被Provisioning的五个阶段折腾得够呛。今天咱们把它拆开揉碎了讲清楚。
4.1 Provisioning的本质:从未配网到已配网
说白了,Provisioning就是让一个未配网的设备(我们叫它Unprovisioned Device)和一个配网者(Provisioner)之间建立信任关系。配网者通常是网关、手机App或者一个专门的配置工具。
整个过程分五步走:
- 广播(Beaconing)——设备告诉周围“我在这儿,快来配我”
- 邀请(Invitation)——配网者问设备“你支持什么能力?”
- 交换公钥(Exchange Public Keys)——双方亮出身份,建立安全通道
- 认证(Authentication)——确认设备确实是你要配的那个
- 分发数据(Distribution)——把NetKey、AppKey、IV Index等关键信息发给设备
核心要点:Provisioning完成后,设备就拥有了NetKey和AppKey,正式成为Mesh网络的一员。之后它才能收发Mesh消息。
4.2 广播与邀请:设备如何被发现
未配网的设备会周期性发送一种特殊的广播包,叫Unprovisioned Device Beacon。这个包里面包含设备的UUID和OOB(带外)信息类型。
配网者扫描到这些广播后,会发起一个Provisioning Invite。设备收到邀请后,会回复自己的能力信息,比如:
- 支持的算法(目前主要是FIPS P-256椭圆曲线)
- 公钥类型(是否支持OOB方式交换)
- 支持的认证方法(Output OOB、Input OOB、静态OOB、无OOB)
- 设备能显示多少位数字、能输入多少位数字
我的经验:在实际项目中,我建议尽量使用OOB认证,哪怕只是简单的数字显示+人工确认。纯无OOB的方式虽然开发省事,但安全性太差。有一次客户要求所有灯具必须支持Output OOB,用LED闪烁次数做认证——虽然麻烦点,但确实安全多了。
4.3 公钥交换与安全通道建立
这一步很关键。配网者和设备各自生成一个椭圆曲线密钥对(私钥+公钥),然后交换公钥。交换方式有两种:
| 交换方式 | 说明 | 适用场景 |
|---|---|---|
| 直接交换 | 公钥通过蓝牙广播直接发送 | 开发调试、安全要求低的场景 |
| OOB交换 | 公钥通过二维码、NFC、串口等方式传输 | 生产环境、安全要求高的场景 |
公钥交换完成后,双方用ECDH算法计算出共享密钥。这个共享密钥会用来加密后续的所有Provisioning数据。说白了,从这一步开始,配网通道就是加密的了。
注意:ECDH计算出的共享密钥只是临时会话密钥。配网完成后,这个密钥就作废了。设备入网后用的加密密钥是NetKey和AppKey,跟这个临时密钥不是一回事。
4.4 认证:确认是你,不是别人
认证阶段是为了防止中间人攻击。配网者会生成一个随机数,要求设备用某种方式证明自己就是那个物理设备。
认证方法有四种:
- Output OOB——设备显示一串数字,人工输入到配网者
- Input OOB——配网者显示一串数字,人工在设备上输入
- 静态OOB——设备出厂时预置一个密钥,配网时自动比对
- 无OOB——不认证,直接信任
我记得有个项目,客户要求用手机App给智能灯配网。灯的硬件只有一颗LED,没法显示数字。最后我们用了Input OOB方案:App上显示6位数字,用户通过灯的物理按键输入。虽然用户体验差了点,但安全合规过了。
4.5 数据分发:NetKey与AppKey的生成
认证通过后,配网者会生成并分发三样核心数据:
- NetKey(网络密钥)——128位随机数,用于加密网络层的消息
- AppKey(应用密钥)——128位随机数,用于加密应用层的消息
- IV Index(初始向量索引)——32位值,用于防止重放攻击
生成方式很简单:配网者调用一个安全的随机数生成器,产生128位随机数作为NetKey和AppKey。关键是要保证随机数的质量,不能用伪随机或者固定值。
重要:NetKey是网络层的共享密钥,同一个网络内的所有设备共享同一个NetKey。AppKey是应用层的密钥,不同应用可以使用不同的AppKey。比如灯控用AppKey A,门锁用AppKey B,两者互不干扰。
4.6 密钥分发的完整流程
配网者把数据打包成Provisioning Data PDU,用前面建立的会话密钥加密后发送给设备。设备收到后解密并存储。整个过程如下:
Provisioner → Device: Provisioning Data PDU
- Network Key (NetKey)
- Application Key (AppKey)
- IV Index
- Unicast Address (设备单播地址)
- Device Key (设备密钥,用于后续配置)
设备收到后,会回复一个Provisioning Complete PDU,表示配网成功。之后设备就进入Configured状态,可以收发Mesh消息了。
我的建议:在实际部署中,NetKey和AppKey最好由配网者统一管理,不要硬编码在设备固件里。我曾经见过一个项目,所有设备出厂时烧录了相同的NetKey——结果一旦泄露,整个网络都得重新配网。正确的做法是:设备只存一个根密钥,NetKey和AppKey在配网时动态下发。
4.7 配网流程全景图
下面这张图把整个Provisioning过程串起来了。你可以看到从设备广播到最终入网的完整路径:
4.8 避坑指南:我踩过的几个坑
做Provisioning开发时,有几个地方特别容易出问题。我把自己踩过的坑列出来,你们可以少走弯路:
- 随机数质量——NetKey和AppKey必须用硬件随机数生成器,不能用软件伪随机。有一次我用了一个简单的rand()函数,结果配网后设备之间通信老是失败——后来发现是密钥重复了。
- OOB超时——认证阶段有超时限制,一般是60秒。如果用户输入太慢,配网会失败。建议在UI上给用户一个倒计时提示。
- 设备地址冲突——配网者分配单播地址时,要确保不重复。我见过一个系统,两个设备被分配了同一个地址,结果消息乱飞。
- IV Index同步——配网时下发的IV Index必须和网络当前值一致,否则设备无法解密消息。
重要提醒:配网过程中,配网者和设备之间的通信是加密的,但配网者本身的安全性同样重要。如果配网者被攻破,整个网络的密钥都会泄露。所以配网者最好运行在安全环境中,比如网关的TEE(可信执行环境)里。
4.9 小结
Provisioning是Mesh网络的基础。你想想看,没有这一步,设备之间连最基本的信任都没有,更别提安全通信了。NetKey和AppKey的生成与分发,说白了就是给每个设备发一张“身份证”和一把“钥匙”。
嗯,这部分内容就到这里。配网搞定了,设备入网了,接下来才能谈消息的收发和路由。不过那是后面章节的事了。