BLE Mesh(六)配网流程

2023-05-16

配网流程

  • 概述
  • 配网协议
    • 配网承载层(Provisioning Bearer)
    • 配网协议(Provisioning Protocol)
  • 流程详解
    • 发送Beacon信号
    • 邀请
    • 交换公共密钥
    • 认证
      • 输出带外(Output OOB)
      • 输入带外(Input OOB)
      • 静态带外(Static OOB) 或无带外(No OOB)
      • 检查确认值(Check Confirmation Value)
      • 确认值检查(Confirmation Value Check)
    • 配置数据分发
  • 参考资料

概述

配网流程(Provisioning)是向蓝牙 Mesh 网络(如灯泡)添加新的未经配置设备的过程。该过程由配网器(Provisioner) 进行管理。配网器和未经配置设备遵循蓝牙 Mesh 规格中定义的固定过程。配网器向未经配置设备提供使其成为蓝牙 Mesh 节点的配置数据(provisioning data)。

配网器通常是运行配网器应用程序的智能手机或其它移动设备。尽管每个网络只需要一台配网器来执行配网,但可用的配网器可以有多台。

完整的配网过程必须在更高的层面完成两项重要任务:

  • 验证未经配置的设备。在蓝牙 Mesh 网络中,一个小空间中可能存在几台、几十台或数百台设备。执行认证是为了确保与配网器进行交互的设备就是用户想要配置的设备。
  • 与未经配置的设备建立安全链接,并与之共享相应的信息。在流程的最后,原本未经配置的设备将成为蓝牙 Mesh 网络中的节点。

配网协议

蓝牙 Mesh 规格中定义了配网协议,该协议定义了配网流程中用于在配网器和新的未经配置设备之间进行通信的标准流程以及 PDU。下图描绘了完整蓝牙 Mesh 协议栈之外的配网协议栈。

mesh 系统架构与配置协议栈

从下到上的组件如下:

配网承载层(Provisioning Bearer)

配网承载层实现了配网 PDU 在配网器和未经配置设备之间的传输。定义的两个配网承载层包括:

  • PB-ADV:指通过蓝牙广播信道进行设备配置的配网承载层。PB-ADV 承载层用于发送通用配网 (Generic Provisioning) PDU。支持 PB-ADV 的设备应尽可能执行占空比接近 100% 的被动扫描,以避免遗漏任何发送来的通用配网 PDU。

  • PB-GATT:指使用来自代理协议的蓝牙 Mesh 代理(proxy)PDU 来进行设备配置的配网承载层。代理协议能使节点通过面向连接的低功耗蓝牙(Bluetooth Low Energy)承载层来收发网络 PDU、mesh Beacon、代理配置消息和配网 PDU。PB-GATT 在 GATT 操作中包含了配网 PDU,涉及 GATT 配网服务,同时能在配网器不支持 PB-ADV 时供其使用。

配网协议(Provisioning Protocol)

定义对于配网 PDU、行为和安全性的要求。了解配网协议将有助于您根据应用需求选择合适的验证方法。

配网协议定义了 10 种配网PDU:

  1. 配置邀请 (Provisioning Invite)
  2. 配置能力 (Provisioning Capabilities)
  3. 配置状态 (Provisioning State)
  4. 配置公钥 (Provisioning Public Key)
  5. 配置输入完成 (Provisioning Input Complete)
  6. 配置确认 (Provisioning Confirmation)
  7. 配置随机 (Provisioning Random)
  8. 配置数据 (Provisioning Data)
  9. 配置完成 (Provisioning Complete)
  10. 配置失败 (Provisioning Failed)

流程详解

配网流程包括五个阶段:

  1. 发送 Beacon 信号:如果未经配置的设备支持 PB-ADV承载层,则其作为未经配置设备 Beacon 进行广播;如果使用的是 PB-GATT 承载层,则发送可连接的广播数据包。这就向配网器(Provisioner)表明未经配置的设备已做好准备,可进入配网流程。
  2. 邀请:配网器(Provisioner)邀请未经配置的设备发送自身配置功能信息。
  3. 交换公共密钥:在此阶段,根据未经配置设备的功能,配网器(Provisioner)选择合适的验证方法,并通知未经配置设备将要采取的方式。之后,配网器和未经配置设备会创建一个椭圆曲线公私密钥对并交换公钥。然后,每台设备使用自己的私钥和对等设备的公钥来计算对称密钥,即 ECDHSecret。该密钥用于验证对端设备的身份。
  4. 认证:在此步骤中,配网器使用所选的验证方法,对未经配置设备进行验证。
  5. 配置数据分发:认证步骤完成之后,就可以确保在配网器(Provisioner)和未经配置设备之间建立的承载层的安全,然后就进入配网(Provisioning)过程中最重要的一步:导出并分发配置数据(provisioning data)。

发送Beacon信号

Beacon 是低功耗蓝牙的传统应用场景。想象一下,一个 GAP 外设(如智能手表或活动跟踪器)希望与 GAP 中央设备(如智能手机或平板电脑)连接。 GAP 外设切换到广播状态并开始发送其广播数据包。GAP 中央设备扫描广播数据包以发现其它设备并接收相关基本信息。蓝牙 Mesh 配置使用的也是相同的广播机制。

如果未经配置的设备支持 PB-ADV 承载层,则其作为未经配置设备 Beacon 进行广播。这涉及指定的数据包格式,且未经配置设备通过此方式来使自身被配网器 (Provisioner) 发现。

当未经配置设备使用 PB-GATT 承载层时,一项称为“Mesh 配置服务”的 GATT 服务会支持整个配网流程,同时支持与配网器的交互。在发送 Beacon 信号阶段,未经配置设备会发送包括 mesh 配置服务 UUID 的广播数据包,它会被配网器通过标准的低功耗蓝牙扫描程序发现。

邀请

在发送 Beacon 信号之后,配网器和未经配置设备会建立 PB-ADV 或 PB-GATT 配网承载层(provisioning bearer)。然后,配网器发送一个配置邀请 PDU,设备通过配置能力 PDU 对其作出响应。

配置邀请 PDU 包括 Attention Duration 字段,其指示了未经配置设备的主要元素应采用某种视觉指示方式,并在多长的时间内吸引用户的注意力。

配置能力 PDU 包括:

  • 设备支持的元素数量;
  • 支持的一组安全算法;
  • 使用带外(OOB)技术实现的公共密钥可用性;
  • 该设备向用户输出值的能力;
  • 该设备允许用户输入值的能力。

配置邀请

上图中的流程图让人联想到低功耗蓝牙中的配对过程。低功耗蓝牙配对采用的配对特性交换类似于蓝牙 Mesh 配置程序中的配置邀请阶段。在配置邀请阶段,目的是向配网器(Provisioner) 提供有关未经配置设备功能的信息。有了这些信息,配网器就能决定下一步该如何进行。

交换公共密钥

信息加密涉及两项基本技术:对称加密(也称为密钥加密)和非对称加密(也称为公钥加密)。

  • 对称加密采用相同的密钥进行加密和解密。只要发送设备和接收设备都知道密钥,就能够解密所有使用此密钥加密的信息。然而,很难安全地通过链路交换密钥并防止其落入坏人之手。
  • 非对称加密使用两个相关的密钥(即一个密钥对)来解决上述问题:公钥和私钥。公钥免费提供给任何可能想向您发送消息的人。私钥则为保密,只有你自己知道。使用公钥加密的任何消息(文本、二进制文件或对称密钥)只能通过应用相同的算法、且仅能使用与之匹配的私钥进行解密。这意味着您不必对通过链接传递公钥的过程有任何担忧,因为它们仅用于加密而非解密。然而,非对称加密比对称加密慢一些,且需要更高的处理能力来进行消息内容的加密和解密。

在蓝牙 Mesh 用例中,大多数设备基于嵌入式芯片组或模块,因此无法使用计算成本昂贵的非对称加密技术来对每个消息进行加密/解密。对称加密更适合于不具备非对称加密所需处理能力的设备,但如何安全地交换并使用密钥仍然是一大问题。蓝牙mesh采用了非对称和对称加密结合的方式来解决这一问题。

  • 对称加密:在蓝牙 Mesh 网络中传输的每个消息都使用 AES-128 密码加密。 AES-128 算法是常用的对称加密/解密引擎,常用于嵌入式平台。
  • 非对称加密:椭圆曲线 Diffie-Hellman(ECDH)是一种匿名密钥协商协议,允许具有椭圆曲线公私密钥对的双方在非安全信道上建立共享保密信息。ECDH 在蓝牙 Mesh 配置中的目的是在配网器和未经配置设备之间创建安全链路。它使用公钥和私钥来分发对称性密钥,两台设备随后可将其用于后续消息的加密和解密。

在交换公钥阶段,有两种交换 ECDH 公钥的可能方式。它们可以通过蓝牙链路、或 OOB 隧道进行交换。在配置邀请阶段,未经配置的设备已经报告了是否支持通过 OOB 隧道发送自身公钥。如果是,则配置设备可继续使用它,并通过发送配置开始 PDU 来通知未经配置的设备。

如果未经配置设备的公钥可通过 OOB 隧道获得,则临时公钥从配网器发送到设备,并采用合适的 OOB 技术(例如二维码),从未经配置的设备中读取静态公钥,如图所示。

未经配置设备采用OOB方式进行的公钥交换

否则,双方的公钥都会经由下图中所示的蓝牙链路进行交换。

未经配置设备的公钥未知时的公钥交换

ECDHSecret = P-256 (私钥,对等公钥)

在该等式中,P-256 即 FIPS 186-3 中定义的 FIPS-P256 曲线。

认证

在此步骤中,配网器使用所选的验证方法,对未经配置设备进行验证。有三种可用的验证方法(OOB, Out-Of-Band):输出 OOB(Output OOB)、输入 OOB(Input OOB)、以及静态 OOB(Static OOB)或无 OOB(No OOB)。

输出带外(Output OOB)

若选择的是输出带外(Output OOB)验证方法,则未经配置设备会选择一个随机数,并通过与其功能兼容的方式输出该数字。例如,如果未经配置设备是一个灯泡,则它能够闪烁指定的次数。如果设备具有 LCD 屏幕,则可以将随机数显示为多位数值。配网器(Provisioner)的用户需要输入观察到的数字,来验证未经配置的设备。输出带外验证方法的工作流程如下图所示。

通过输出OOB进行验证

输入随机数后,配网器(Provisioner)生成并检查确认值。无论采用哪种验证方式,整个验证步骤中的检查确认值(check confirmation value)计算方式都是相同的。

输入带外(Input OOB)

输入带外(Input OOB)验证方法与输出带外(Output OOB)方法类似,但设备的角色相反。配网器(Provisioner)生成并显示随机数,然后提示用户采取适当的操作,将随机数输入未经配置的设备。以照明开关为例,用户可以在一定时间内数次按下按钮,以这种形式输入随机数。

与输出带外验证(Output OOB)相比,输入带外(Input OOB)方法需要发送一个附加的配置协议 PDU。在完成认证操作之后,未经配置的设备向配网器发送一个配置输入完成 PDU(Provisioning Input Complete PDU),通知其随机数已输入完成。随后进入到执行检查确认值操作的步骤。

通过输入OOB进行验证

静态带外(Static OOB) 或无带外(No OOB)

在输入带外或输出带外都不可用的情况下,配网器(Provisioner)和未经配置的设备可采用静态带外(Static OOB)验证或无带外(No OOB)验证:采用静态 OOB 信息;或静态 OOB 信息不可用,直接以数值 0 代替。在此情况下,配网器和未经配置的设备各自生成一个随机数,然后进行检查确认值操作。

检查确认值(Check Confirmation Value)

无论采用何种验证方法,都会进行确认值生成和检查。根据蓝牙 Mesh 规格,配网器(Provisioner) 和未经配置设备应分别计算确认值。这两个值被称为 ConfirmationProvisioner 和 ConfirmationDevice。这两个值的计算都使用一系列相同的函数,不同之处仅在于所使用的随机数输入。

让我们来看看用于确认值生成的算法。下图是一个流程图,其中包括了几轮 AES-CMAC 和 SALT 生成[1]。该流程图对于 ConfirmationProvisioner 和 ConfirmationDevice 值均适用。

  • 如果由配网器(Provisioner)执行输入,则从一个名为 RandomProvisioner 的值开始(下图中以蓝色表示),并生成 ConfirmationProvisioner 值。
  • 如果由未经配置设备执行输入,则从一个名为 RandomDevice 的值开始(下图中以绿色表示),并生成 ConfirmationDevice 值。

确认值生成图

确认值检查(Confirmation Value Check)

当确认值生成之后,两台设备就会进行交换,并且都会检查接收值的完整性。图4表示确认值检查的过程。

确认过程的开始就是配网器(Provisioner)将其随机数 RandomProvisioner 发送到未经配置的设备。未经配置设备使用它来重新计算确认值,并与之前接收的确认值进行比较,进行验证。

确认值检查

  • 如果由未经配置设备计算所得的确认值与接收到的 ConfirmationProvisioner 不匹配,则配网(Provisioning)过程将被中止。
  • 如果由未经配置设备计算所得的确认值与接收到的 ConfirmationProvisioner 匹配,则未经配置设备将其 RandomDevice 值发送给配网器。

然后,配网器(Provisioner) 使用相同的过程来重新计算确认值,并通过比较计算所得值与先前接收值来进行验证。

  • 如果由配网器(Provisioner) 计算所得的确认值与接收到的 ConfirmationDevice 不匹配,则配网(Provisioning)流程将被中止。
  • 如果由配网器(Provisioner) 计算所得的确认值与接收到的 ConfirmationDevice 匹配,则表示验证成功。后续只要配网器(Provisioner)和未经配置设备完成配网流程的第五步:配置数据分发,则未经配置设备就能成为蓝牙 Mesh 网络中的节点(node)。

配置数据分发

认证步骤完成之后,就可以确保在配网器(Provisioner)和未经配置设备之间建立的承载层的安全,然后就进入配网(Provisioning)过程中最重要的一步:导出并分发配置数据(provisioning data)。配网器(Provisioner) 负责生成配置数据,配置数据由多个数据项组成,包括一个称为网络密钥 (NetKey) 的安全密钥。下表列出了配置数据字段。

字段大小(字节)注释
网络密钥16简称 NetKey。NetKey 确保网络层(network layer)通信的安全,并在网络中所有节点(node)之间共享。是否拥有给定的 NetKey 定义了给定蓝牙 Mesh 网络或子网的成员资格。为设备赋予网络的 NetKey 是配网(Provisioning)流程的主要结果之一。
配网器(Provisioner) 在对要添加到网络中的首台设备进行配置时创建 NetKey。
设备密钥16简称 DevKey,只有配网器(Provisioner)和被配置的设备拥有的唯一安全密钥 。
密钥索引2由于 NetKey 太长,无法在单段消息中传输。为使消息传递尽可能高效,会向密钥分配一个全球唯一的12位索引值,称为密钥索引,用作密钥的短标识符。消息中包括密钥索引值,它可能以配置客户端(Configuration Clients)维护的密钥列表为参考。
标志1标志位掩码 - 指示关联密钥的状态。
IV 索引4IV(初始化向量)索引是一个32位的值,被网络中的所有节点 (node)共享。其目的是在计算消息随机值时提供熵(随机性)。
单播地址2新节点中主要元素的单播地址(Unicast Address)。

为安全地进行配置数据分发,配网器(Provisioner)采用AES-CCM [2],借助共享的会话密钥(SessionKey)对配置数据(provisioning data)进行加密,配网器和未经配置设备都会进行计算。 AES-CCM需要三个输入参数:会话密钥、会话随机数和纯文本。纯文本参数值包含需要被加密的配置数据。设备密钥(DevKey)、会话密钥(SessionKey)和会话随机数(SessionNonce)的值通过图所示的过程导出。

DevKey / SessionKey / SessionNonce生成过程

从图中可以看出:

  • 如果将 prsk(绿色)的输入值代入k1函数中,则会生成 SessionKey。这是用于配置数据加密的关键。
  • 如果将 prsn(黄色)的输入值代入k1函数中,将生成 SessionNonce。这是用于配置数据加密的随机值。
  • 如果将 prdk(蓝色)的输入值代入k1函数,则将生成 DevKey。

配网器(Provisioner)和未经配置设备都需要生成会话密钥(SessionKey)和会话随机数(SessionNonce)。当 SessionKey 和 SessionNonce 值准备就绪时,配网器将对包含导出配置数据的配置数据 PDU (Provisioning Date PDU) 进行加密,并将其发送至未经配置的设备。此处,相同的 SessionKey 和 SessionNonce 值也可用来对接收到的数据进行解密。

至此,配网流程完成。两台对等设备都已知晓新的设备密钥(DevKey)和全网的网络密钥(NetKey),这就意味着我们的新设备已成为蓝牙 Mesh 网络中的节点(node)和成员。

参考资料

  • 解密蓝牙mesh系列 | 第九篇
  • 解密蓝牙mesh系列 | 第十篇
  • Provisioning a Bluetooth Mesh Network Part 1
  • Provisioning a Bluetooth Mesh Network Part 2
  • [1] 有关AES-CMAC和SALT的更多信息,请参阅《蓝牙mesh - 安全概述》。
  • [2] 有关这些术语的更多信息,请参阅《蓝牙mesh - 安全概述》。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BLE Mesh(六)配网流程 的相关文章

  • 蓝牙协议介绍

    1 广播 ADV Advertising 1 1 BLE 报文结构 BLE引入access address 概念 用来指明接收者身份 概 其中 0x8E89BED6 这个access address 比较特殊 它表示要发给周边所有设备 即广
  • Android - BlueTooth BLE 之 Central 与 Peripheral

    一 前言 Andorid 5 0 之前是无法进行 外围设备开发的 在Android 5 0 API 21 android bluetooth le包下 新增加 Scaner相关类和 Advertiser 相关类 目前最后使用Scanner相
  • ESP32-C3 应用 篇(实例二、通过蓝牙将传感器数据发送给手机,手机端控制 SK6812 LED)

    ESP32 C3 蓝牙部分我们学习了GATT 本文尝试使用蓝牙做一个简单的小应用 目录 前言 一 整体框架 二 数据传输部分 2 1 添加温湿度驱动组件 2 2 传感器数据传输程序 再次说明 ESP GATTS READ EVT 事件 2
  • nRF52832 — 串口BLE例程逐行解析【转载】

    原文链接 http blog csdn net u011034150 article details 50617686 转载文章 若有不妥 通知后我会立即删除 本讲逐行代码解析官方串口BLE例程demo 主要分一下几个部分 1 Main函数
  • NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3)

    前言 SDK版本15 3 评估板 pca10040 在 uart 的例程中添加 DFU 功能 使用 s132 的协议栈 因为官方的 BootLoader 工程用的是s132的协议栈 一 准备工作 在开始实验之前必须先准备以下软件 gcc a
  • Mesh(802.11s)组网 — 基于OpenWRT路由器

    一 mesh网络 1 mesh网络拓补图 2 介绍 二 OpenWRT路由器Mesh网络配置 1 准备阶段 说明 本次测试用2台单WiFi路由器作为测试 wifi用于组建Mesh网络连接 因此内网已无额外WiFi可以提供使用 因此局域网用有
  • 适用于 C/C++ 的轻量级 OBJ 网格文件加载器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在寻找一个用于 C 或 C 的简单轻量级 Wavefront OBJ 网格文件阅读器 即 给定 OBJ 格式的网格 从文件中读取它 并使其可访问
  • 物理实体的 Gmsh 问题

    我有一个 geo我用 python 脚本编写的文件 这个的主要用途 geo文件的作用是构造并保存三角网格 在 gmsh 中 您可以使用物理命令标记感兴趣的实体 例如Physical Point Physical Line etc 来了 ge
  • SceneKit:关于像 Tron 光循环一样再现发光光迹的建议

    目标是在 SceneKit 中重现类似于下图的光迹 路径不需要那么详细 但我们的想法是实现类似的视觉效果 我们尝试使用不透明度约为 0 5 的薄立方体 我们将大约 200 个灯串在一起 并将它们连接到一个节点上 作为光迹 那根本没有表现 另
  • 无论旋转如何,跟踪增强面 (ARCore) 的面网格顶点

    我正在尝试跟踪面部表情 例如扬眉 微笑 眨眼等 在 ARKit 中 我可以使用 blendShapes https developer apple com documentation arkit arfaceanchor 2928251 b
  • 表面网格到体积网格

    我有一个使用 Meshlab 从点云生成的封闭表面网格 我需要为此获得一个体积网格 这样它就不是一个空心物体 我想不通 我需要获取 stl 文件进行打印 谁能帮我获得体积网格 我更喜欢简单的解决方案而不是复杂的算法 给定一个定向的水密表面网
  • 如何计算具有三角形面的网格的质心?

    我想根据以下描述计算网格的新质心 但我不想使用 Blender 的内置函数来计算质心 如所解释的here https blender stackexchange com questions 14294 how to recenter an
  • 环境错误:Gmsh 版本必须 >= 2.0

    我是 fipy 的新手 所以如果我问一些应该显而易见的问题 请原谅我的无知 但我无法运行已经存在的 并且在其他机器上工作的 脚本 无法获取EnvironmentError Gmsh version must be gt 2 0 我可能在安装
  • 删除 Meshlab 或 vcglib 中的自相交

    如何使用 Meshlab 应用程序或 vcglib 消除网格的自相交 这超出了范围 但 CGAL 中有一些函数 这仍然是实验性的 没有记录 但您可以使用该功能remove self intersections https github co
  • 为什么从搅拌机导出到 Unity 时我的 (FBX) 网格体有孔?

    我现在正在学习雕刻我的角色 当我将 FBX 文件从 Blender 导出到 Unity 时 网格物体的脸上有一个巨大的洞 我该如何预防 解决这个问题 它在 mixamo 中工作得很好 在此输入图像描述 https i stack imgur
  • Unity:将网格物体轻轻包裹在其他网格物体周围?

    给定一个网格 如左侧的立方体对象 和另一个自定义的球状网格 右侧 如果更容易的话 它可以是另一种形状 Unity 和 C 中的一个在运行时如何将第二个网格轻轻包裹在第一个网格周围 谢谢 下面的方法 借助 VirtualMethodStudi
  • 在 Python 中创建二维非矩形形状的三角形网格

    假设我有一组点定义二维平面中非矩形形状的周长 我需要一个函数来创建三角形网格划分 在其中可以修改三角形单元的数量并返回每个单元的 x y 坐标 谢谢 你可能应该看看 dmsh https github com nschloe dmsh py
  • CGAL:从网格中读取顶点和三角形

    我只是花了几个小时在 Visual Studio C 中使用 CGAL 来尝试了解网格的工作原理 我想要得到的是对顶点和三角形列表的访问 顶点以 double 3 形式 三角形以 int 3 形式 这是我正在编写的脚本 http doc c
  • 在网格挤出过程中计算 UV 坐标

    我目前正在为平面形状实现网格挤出算法 让我们假设为矩形 当我拉伸这个矩形时 我为 3d 形状创建了四个新边 产生 8 个新三角形 和一个新底部 当我复制所有顶点以使最终的立方体有 24 个顶点时 这种方法效果很好 但我现在想避免这些额外的顶
  • 如何在 R 中导入并绘制三角形网格?

    我想在 R 中绘制我的模型输出 它是格式为的三角形网格 x1 y1 z1 x2 y2 z2 x3 y3 z3 value 每行代表一个三角形 我想用以下方法绘制这些三角形value作为规模 mymesh lt structure c 0 9

随机推荐