4. 设备入网与配置

配网(Provisioning),说白了就是把一个还没入网的设备,正式“拉进”蓝牙Mesh网络的过程。很多初学者觉得这步就是配个对,其实里面藏着五个环环相扣的阶段。我刚开始调Mesh的时候,就因为在认证阶段踩了坑,折腾了两天才找到原因。

这五个阶段分别是:Beaconing(信标广播)、邀请(Invitation)、交换公钥(Exchange Public Key)、认证(Authentication)、分发数据(Distribution of Provisioning Data)。咱们一个一个拆开讲。

核心要点:配网过程是 Provisioner(配网器,通常是手机或网关)与未配网设备(Unprovisioned Device)之间的一对一交互。整个流程走完,设备才能拿到 NetKey、AppKey 等网络身份凭证。

蓝牙Mesh配网五阶段流程图 配网五阶段流程 Beaconing 广播自身存在 邀请 交换能力信息 交换公钥 建立安全通道 认证 校验设备身份 分发数据 下发网络密钥 说明: • 每个阶段都有明确的PDU(协议数据单元)交互 • 前三个阶段完成后,才进入认证环节 • 认证通过后,Provisioner 才会下发网络配置数据

4.1 Beaconing 阶段:设备在喊“我在这里”

未配网设备上电后,会周期性地广播一种特殊的AD Type——Mesh Beacon。这个Beacon里包含一个关键字段:Device UUID(设备唯一标识)。Provisioner 在扫描时,就是靠这个 UUID 来识别哪些设备还没入网。

我记得第一次抓包分析时,发现有些设备广播间隔设得太短,导致信道拥塞。后来我建议把间隔设在 100ms~200ms 之间,既不影响发现速度,也不至于把空口占满。

小技巧:如果你用 nRF Connect 抓包,可以在广播包里看到 0x2B(Mesh Beacon AD Type)。如果看不到,说明设备可能已经配过网了,或者广播参数没配对。

4.2 邀请阶段:互相摸摸底

Provisioner 发现设备后,会发一个 Provisioning Invite PDU。设备收到后,回复自己的 Provisioning Capabilities PDU,告诉 Provisioner:

  • 支持多少种认证方式(OOB类型)
  • 公钥是算法生成的,还是直接用静态的
  • 最大支持多少字节的配网数据

说白了,这就是双方在握手阶段互相“亮底牌”。你想想看,如果设备不支持你打算用的认证方式,那后面就没法玩了。

Capabilities 字段 含义 常见值
Number of Elements 设备包含的元素数量 1(单元素设备最常见)
Algorithms 支持的加密算法 0x01(FIPS P-256)
Public Key Type 公钥类型 0x00(OOB)、0x01(计算生成)
Static OOB Type 是否支持静态OOB 0x00(不支持)、0x01(支持)
Output OOB Size 输出OOB最大位数 0~8
Input OOB Size 输入OOB最大位数 0~8

4.3 交换公钥阶段:搭一条安全通道

这一步很关键。Provisioner 和设备会交换各自的公钥,然后通过 ECDH(椭圆曲线迪菲-赫尔曼) 算法,算出一个共享密钥。后续所有配网数据,都用这个共享密钥加密传输。

公钥交换有两种方式:

  • 计算生成(No OOB):双方各自在本地生成临时公私钥对,直接交换公钥。简单,但安全性一般。
  • 静态OOB(Static OOB):公钥提前写在设备上,通过二维码、NFC等方式传给 Provisioner。安全性更高。

我个人习惯在生产环境中用静态OOB。虽然多了一步扫码或NFC读取的操作,但能有效防止中间人攻击。我曾经在一个智能灯控项目里,就是因为偷懒用了No OOB,结果测试时发现有人能伪造设备入网……后来全部改成了静态OOB。

注意:交换公钥阶段完成后,双方会生成一个 Provisioning Salt 和 Session Key。这两个值在后续认证和数据分发中都会用到。如果这里出错了,后面所有步骤都会失败。

4.4 认证阶段:验明正身

认证阶段,说白了就是 Provisioner 要确认“你确实是你声称的那个设备”。认证方式取决于 Capabilities 阶段协商的结果:

  • No OOB:不认证,直接通过。最不安全,生产环境慎用。
  • Static OOB:设备端预置一个静态密钥,Provisioner 通过扫码等方式获取后,双方比对。
  • Output OOB:设备通过屏幕显示、LED闪烁、蜂鸣器等方式输出一串随机数,用户输入到 Provisioner 中。
  • Input OOB:Provisioner 显示一串随机数,用户通过按键、触摸等方式输入到设备中。

嗯,这里要注意:认证过程中,双方会交换 Provisioning Confirmation PDU 和 Provisioning Random PDU。Confirmation 是一个哈希值,Random 是生成这个哈希的随机数。Provisioner 收到 Random 后,自己算一遍哈希,如果跟 Confirmation 对得上,认证就通过了。

我曾经遇到过一个坑:设备端生成的 Random 值长度不对,导致 Confirmation 一直校验失败。查了两天才发现是随机数生成器的种子没初始化好。从那以后,我每次都会在代码里加一个断言,检查 Random 的长度是不是 16 字节。

4.5 分发数据阶段:给设备发“身份证”

认证通过后,Provisioner 会生成并下发一组配网数据。这些数据包括:

  • NetKey(网络密钥):设备入网后的网络身份,所有网络层通信都靠它加密。
  • Key Index:NetKey 的索引,用于标识使用哪个密钥。
  • IV Index:初始向量索引,用于网络层加密的计数器。
  • Unicast Address(单播地址):设备在网络中的唯一地址,由 Provisioner 分配。
  • Flags:一些标志位,比如 Key Refresh 标志、IV Update 标志等。

这些数据通过 Provisioning Data PDU 发送,使用前面生成的 Session Key 加密。设备收到后,会回复一个 Provisioning Complete PDU,表示配网成功。

关键点:分发数据阶段结束后,设备就正式成为 Mesh 网络的一个节点了。它会用 NetKey 加密后续的所有网络层消息,并用分配到的单播地址与其他节点通信。

配网流程走完,设备才算真正“活”了。你想想看,如果没有这五个阶段的层层校验,随便一个设备都能入网,那 Mesh 网络的安全性就形同虚设了。