4. Mesh网络配置流程:Provisioning(配网)过程详解、AppKey与NetKey的生成与分发

好,咱们进入正题。Mesh网络要跑起来,第一步就是配网——也就是Provisioning。很多初学者觉得配网就是“把设备加进去”,其实没那么简单。我当年第一次调Mesh协议栈时,就被Provisioning的五个阶段折腾得够呛。今天咱们把它拆开揉碎了讲清楚。

4.1 Provisioning的本质:从未配网到已配网

说白了,Provisioning就是让一个未配网的设备(我们叫它Unprovisioned Device)和一个配网者(Provisioner)之间建立信任关系。配网者通常是网关、手机App或者一个专门的配置工具。

整个过程分五步走:

  1. 广播(Beaconing)——设备告诉周围“我在这儿,快来配我”
  2. 邀请(Invitation)——配网者问设备“你支持什么能力?”
  3. 交换公钥(Exchange Public Keys)——双方亮出身份,建立安全通道
  4. 认证(Authentication)——确认设备确实是你要配的那个
  5. 分发数据(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的生成

认证通过后,配网者会生成并分发三样核心数据:

  1. NetKey(网络密钥)——128位随机数,用于加密网络层的消息
  2. AppKey(应用密钥)——128位随机数,用于加密应用层的消息
  3. 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过程串起来了。你可以看到从设备广播到最终入网的完整路径:

Provisioning 配网流程全景图 1. 设备广播Beacon 2. 配网者发送Invite 3. 交换公钥 4. 认证(OOB) 5. 分发密钥数据 6. 配网完成 设备发送Unprovisioned Device Beacon 包含UUID和OOB能力信息 配网者询问设备支持的能力 设备回复算法、公钥类型、认证方法 ECDH密钥交换,建立安全通道 支持直接交换或OOB交换 防止中间人攻击 Output OOB / Input OOB / 静态OOB 下发NetKey、AppKey、IV Index 以及设备单播地址和设备密钥 设备回复Provisioning Complete 进入Configured状态,可以收发Mesh消息

4.8 避坑指南:我踩过的几个坑

做Provisioning开发时,有几个地方特别容易出问题。我把自己踩过的坑列出来,你们可以少走弯路:

  • 随机数质量——NetKey和AppKey必须用硬件随机数生成器,不能用软件伪随机。有一次我用了一个简单的rand()函数,结果配网后设备之间通信老是失败——后来发现是密钥重复了。
  • OOB超时——认证阶段有超时限制,一般是60秒。如果用户输入太慢,配网会失败。建议在UI上给用户一个倒计时提示。
  • 设备地址冲突——配网者分配单播地址时,要确保不重复。我见过一个系统,两个设备被分配了同一个地址,结果消息乱飞。
  • IV Index同步——配网时下发的IV Index必须和网络当前值一致,否则设备无法解密消息。

重要提醒:配网过程中,配网者和设备之间的通信是加密的,但配网者本身的安全性同样重要。如果配网者被攻破,整个网络的密钥都会泄露。所以配网者最好运行在安全环境中,比如网关的TEE(可信执行环境)里。

4.9 小结

Provisioning是Mesh网络的基础。你想想看,没有这一步,设备之间连最基本的信任都没有,更别提安全通信了。NetKey和AppKey的生成与分发,说白了就是给每个设备发一张“身份证”和一把“钥匙”。

嗯,这部分内容就到这里。配网搞定了,设备入网了,接下来才能谈消息的收发和路由。不过那是后面章节的事了。