BLE 技术(七)--- BLE MESH 是如何设计的?

文章目录

前言

前篇博文BLE协议栈设计与演进介绍过,当BLE 设备数量比较多时,常用的大规模组网方式有IP 组网和MESH 组网两种。如果熟悉TCP/IP 协议,不难理解 IP 组网就是将BLE 作为数据链路层,在其上添加TCP/IP协议栈接入Internet,如果需要接入云平台实现大规模远程监控,可以借助MQTT 协议的消息发布-订阅模型来实现。

很多场景下,我们并不需要每台设备都接入Internet,而是需要大量的BLE 设备在本地组成一个智能局域网,比如楼宇智能照明网络、传感器网路等。为此,SIG 于2017 年发布了Bluetooth mesh networking 规范,使用MESH 网络拓扑结构可以实现本地大规模自组网,BLE MESH 有哪些特点或优势?又是怎么实现的呢?

MESH 类似于TCP/IP 协议,是一种网状网络标准,下层需要物理层和数据链路层的支撑,BLE MESH 就是基于BLE 的网状网络标准,允许大量BLE 设备之间进行多对多通信。

BLE MESH 由SIG 于2017 年发布在Mesh ProfileMesh Model 规范中,算是一个比较新的网络协议。蓝牙技术联盟的小码哥(Martin Woolley) 和任凯也写了解密BLE MESH 系列博文可以帮助我们快速了解BLE MESH。

一、BLE MESH 如何定义并传递消息?

学习一个新的协议,不妨将其与已经熟悉的协议做个对比并建立联系。前面介绍了BLE 设备间一对多的广播通信和一对一的连接通信,MESH 网状网络则是多对多的广播通信,三者的网络拓扑结构对比如下:
BLE 技术(七)--- BLE MESH 是如何设计的?

1.1 如何定义MESH 设备的消息?

不管是哪种网络拓扑结构,都是为设备间高效安全的进行数据通信设计的,都有数据的发送方和接收方。广播通信中,Advertiser 发送数据报文,Scanner 接收数据报文,广播通信算是单向不安全通信。连接通信中,则采用了Client – Server 通信架构,Client 请求服务、Server 提供服务,连接通信算是双向安全通信。BLE MESH 网络中的设备包括传感器、照明灯、开关、电机等,既有向特定设备发送控制指令或上传数据的需求,也有接收并处理来自特定设备的查询指令或设置指令的需要,因此MESH 设备间应能支持可靠的双向通信。

双向通讯协议,不管是BLE GATT 还是HTTP / MQTT,都采用Client – Server 通信架构,BLE MESH 也采用了Client / Server 架构承担设备间的通信任务。BLE MESH 目前在商业照明网络和传感网络中应用比较广泛,我们以商业照明中的开关节点和灯泡节点为例,灯泡节点是提供照明服务的Server,开关节点则是请求照明服务的Client,二者的通信架构如下(可对比GATT Client 与GATT Server 的通信架构):
BLE 技术(七)--- BLE MESH 是如何设计的?
BLE 设备的Client 和Server 是基于GATT Service / Profile 的,提供GATT Service 的设备称为GATT Server,请求GATT Service 的设备称为GATT Client。BLE MESH 设备的Client 和Server 则是基于MESH Model 的,比如上图是以Generic OnOff Model 作为示例,提供Generic OnOff 服务的设备称为Generic OnOff Server,请求Generic OnOff 服务的设备称为Generic OnOff Client。什么是MESH Model 呢?

MESH Model 可以类比GATT Service / Profile,是抽象出来的基本功能单位,比如电机、电灯、插座等不同的设备都可以抽象出一个Generic OnOff Model。同样类比一个BLE 外设可以提供多个GATT Services,一个BLE MESH 设备也可以提供多个MESH Model,也即一个MESH 设备可以提供多个基本功能。

BLE MESH 有些术语跟BLE GATT 中的不同,BLE MESH 网络中的设备称为MESH 节点,由于一个设备节点可能包含多个子设备,比如多孔插座、多灯泡灯具、多按键开关等,我们将这些基本的子设备实体称为元素,也即一个节点设备可能包含多个元素,每个元素都是一个独立的子设备 。比如双孔插座或双灯泡灯具设备节点,都包含两个元素:
BLE 技术(七)--- BLE MESH 是如何设计的?

  • Node:已经加入到MESH 网络中的设备,MESH 网络中的每个设备称为一个网络节点,节点设备之间通过MESH 消息报文通信;
  • Element:每个节点设备可能包含了多个独立的子设备,比如多孔插座、多灯泡灯具、多按键开关等,每个独立的子设备都称为一个元素,元素可以理解为MESH 网络中实体设备的基本单位。为方便在MESH 网络中寻址特定的设备,每个元素都会被分配一个在该MESH 网络中唯一的单播地址。为了提高寻址效率,每个节点设备都有一个主元素负责该节点内多个元素的寻址计算。

MESH Model 继续类比GATT Service / Profile,每个GATT Service 可能包含多个Characteristics,通过对Characteristic Value 的Read / Write / Notify / Indicate 实现对GATT Service 的请求或响应。每个MESH Model 则可能包含多个States,通过相应的Messages 来实现对特定State 的Get / Set / Status(可类比Read / Write / Notify),比如灯泡元素可能包含Generic On/Off State 和Generic Level State 两个状态,通过Generic On/Off Set message 可以改变Generic On/Off State,为了实现某个基本功能而定义的Sates、作用于这些状态的Messages、响应这些消息的Behaviors 一起构成了Model,这几者的关系如下(右图是上述双孔插座的元素-模型结构,每个插孔都可以独立测量连接其上的设备消耗的功率信息):
BLE 技术(七)--- BLE MESH 是如何设计的?

  • State:将设备抽象定义为几个可用数值量化表示的工作状态,对设备的控制就相当于是工作状态的变更或切换。比如灯泡可以用On/Off(也即布尔值1/0) 表示开关状态,也可以用0-10 的整数值表示亮度状态,温度传感器可以用0-100 的浮点值表示当前的温度状态等。多个状态之间也可以相互绑定,让一个状态的改变会导致另一个状态的改变,比如将灯泡亮度状态值0 绑定到开关状态值Off、将灯泡亮度状态非零值绑定到开关状态值On(上面右图中的每个橙色方框表示一个状态);
  • Message:在MESH 网络中设备间的通信都是靠发送接收消息完成的,消息是作用于状态的(也即用于获取或改变当前的状态),对于每个状态都定义了一组消息,Client 可以使用这些消息来请求或更改服务端的某个状态值,Server 则定义了必要的状态以及响应状态消息的行为、也可以主动使用消息向特定客户端通知当前的状态值;
  • Model:定义了MESH 设备的基本功能,由于BLE MESH 采用Client – Server 架构通信,Model 也可分为Server Model 和Client Model 两类。Server Model 提供模型实现的服务,包括为实现基本功能服务而定义的States、作用于这些状态的Messages、响应这些消息的Behaviors 等;Client Model 则是请求模型实现的服务,只包括获取或更改特定状态的消息,也即客户端模型没有状态。由于MESH 网络通信的复杂性,部分元素设备可能同时包含Server Model 和Client Model,比如一个冷却泵控制模块包含一个温度传感器(Server Model)和一个水泵开关控制器(Client Model),当温度状态值超过某个设定阈值时打开水泵,这类同时包含状态和控制逻辑的模型称为Control Model,控制模型可以大大丰富各元素或模型间的交互逻辑。
    BLE 技术(七)--- BLE MESH 是如何设计的?

1.2 如何在MESH 中传递消息?

BLE MESH 网络中设备间传输传感器状态数据或者执行器控制指令都是通过消息完成的,消息报文主要在Server Model 和Client Model 之间传递。但MESH 设备间消息的传递是多对多的,Control Model 又增加了消息传递的复杂性,BLE MESH 该采用怎样的消息传递模型来实现这么复杂的MESH 设备间通信需求呢?

博文如何使用消息订阅-发布模型介绍到的消息订阅-发布模型就比较适合大规模物联网设备之间复杂的多对多消息传递,通过解耦消息的订阅者和发布者,很方便网络设备节点的扩展,BLE MESH 也采用了订阅-发布消息模型在MESH 设备节点之间传递消息报文。
BLE 技术(七)--- BLE MESH 是如何设计的?
BLE MESH 作为本地自组网,不适合设置一个像云端服务器这么强大的Broker / Server 来集中维护各设备的订阅列表,MESH 网格网络更接近去中心化的网络拓扑结构,该如何在MESH 自组网中应用订阅-发布消息传递模型呢?

考虑到BLE MESH 设备功能都比较单一,可以将每个功能抽象成一个元素element,每个设备节点可以包含多个元素,每个元素被分配一个单播地址(每个元素中的多个模型可通过Model ID 字段区分),这个单播地址可以作为订阅者和发布者的身份标识。
BLE 技术(七)--- BLE MESH 是如何设计的?
有单播地址自然有组播地址(又细分为Group Address 和Virtual Group Address),每个组播地址表示逻辑上的一个元素群组,我们可以使用组播地址表示同一个主题的订阅者群组。如果发布者要将消息发送给单个元素,目的地址可以直接使用发送对象的单播地址;如果发布者要将消息发送给一组元素,目的地址可以使用组播地址。

每个元素都分配了唯一的单播地址,订阅同一主题的多个元素可以使用组播地址标识,我们就可以在消息报文中包含源地址和目的地址字段(来取代MQTT 报文中的topic 字段),采用网络寻址的方式在MESH 网络中传输报文,就不需要Broker 来集中分发传递全网的消息了。

为了方便MESH 网络中的其它节点,特别是订阅了自己发布地址的节点及时了解自己的活动状态,MESH 网络中的节点也会周期性的向其它节点发送Heartbeats 心跳消息报文(可以类比MQTT 中的PINGREQ / PINGRESP 报文)。MESH 网络中的Heartbeats 心跳消息不仅可以让其它节点(特别是订阅节点)及时了解本节点的活动状态,也可以在本节点启用/禁用某些功能或者改变在MESH 网络中的角色时及时通知其它节点(Heartbeats 消息报文可携带本节点当前可使用的功能信息)。

1.3 如何在MESH 中寻址目的节点?

在MESH 网络中寻址传输消息报文主要有两种方式:

  • 路由寻址转发:在MESH 网络中需要有路由节点,路由节点内维护一张路由表,接收到一个数据包后通过查询路由表获知需要通过哪个端口或连接将数据包转发出去。路由寻址尽量以最短的传播路径到达所有目的节点,数据包传播寻址比较高效,但协议设计相对复杂,比如Zigbee MESH 或Wi-Fi MESH 都是采用这种寻址方式;
  • 受控泛洪广播:在MESH 网络中不需要路由节点,每个节点向周围广播数据包,数据包几乎可以到达全网的所有节点。为了减少泛洪广播造成网络拥塞,控制每个节点对同一个数据包只处理一次,且为每个数据包设置生存时间TTL(通过Heartbeats 报文信息计算合适的TTL 值),尽量减少泛洪数据包对网络资源的消耗。受控泛洪广播协议设计相对简单,每个数据包可通过多条路径到达目的节点,增强了网络传输的可靠性,但数据包广播寻址相对低效,比如SIG BLE MESH 就采用了这种寻址方式。

考虑到BLE MESH 传输的消息报文都比较短小,SIG 采用更简单的受控泛洪广播寻址方式完成消息报文在MESH 网络中的传输。这种寻址方式不需要路由节点,每个设备节点地位差不多(只有中继节点可转发消息报文,是否启用中继功能只是设备节点的一个可配置属性),入网后的设备节点在网络覆盖范围内移动位置不影响通信。BLE MESH 网络的拓扑结构如下:BLE 技术(七)--- BLE MESH 是如何设计的?
上图中的Relay node 并不是路由节点,只是简单的将消息报文再中继广播给附近的设备节点,以便让数据包可以传播到全网所有节点。借助中继节点,BLE MESH 消息报文传播距离或范围可以远超过BLE 通信距离,每个消息的最大生存时间TTL 是127 跳,也即每个数据包最远可以传送到127 倍的BLE 通信距离(假如BLE 传输距离为40 米,BLE MESH 最大传输距离则为5 千米)。

SIG 为了减少BLE MESH 中消息报文的长度,元素的单播地址或组播地址都采用16 位二进制表示,单播地址的最高位为0,因此单播地址理论上限为 215 - 1 = 32767 个,也即BLE MESH 网络中元素的最大数量为32767 个(一个设备节点可能包含多个元素,因此BLE MESH 支持的设备节点数量少于该值)。

MESH 网络中的Heartbeats 消息报文可以携带 InitTTL 值,接收到Heartbeats 消息报文的节点可以通过接收到该消息报文时的RxTTL 值,计算出Heartbeats 消息报文发送节点到接收节点的距离或跳数Hop count(Hop count = InitTTL-RxTTL +1)。借助Heartbeats 消息报文,就可以让每个节点了解距离其它节点的大概TTL,在向其它节点发送消息报文时,就可以据此设置合适的TTL 值,配合减少泛洪数据报文对MESH 网络的带宽消耗,提高受控泛洪广播通信的效率。

注:SIG 给出的BLE MESH 规范采用受控的泛洪广播寻址方式,有些特别的场景可能采用路由寻址更合适或高效,BLE MESH 开发商可以引入路由机制来满足特定的应用需求,可以参阅博文:bluetooth-mesh-network-tutorial

二、BLE MESH 如何保证通信安全?

SIG MESH 采用受控泛洪广播寻址方式传输消息报文,泛洪广播与BLE 广播通信更搭,SIG MESH 主要也是借助BLE 广播报文来承载MESH 消息报文的。BLE 广播通信是不安全的,BLE MESH 如何保证消息报文传输的安全性呢?

2.1 子网隔离与加密认证

保证安全性,通常有两种方案:区域隔离加密认证。一个SIG MESH 网络可以划分为多个子网络,一个加入MESH 网络的设备需要获得该网络的NetKey 才能接收或中继该MESH 网络中的消息(设备入网时会为其分配网络密钥NetKey),入网设备需要接收或中继哪个子网的消息报文就为其分发哪个子网的网络密钥,如果没有相应的子网密钥就不能接收或中继该子网的消息报文,这就是子网间的区域隔离

SIG MESH 网络或子网内的通信安全主要靠加密认证来保证,由于MESH 报文在底层主要靠BLE 广播报文承载,因此需要在网络层对MESH 报文进行加解密处理,即便BLE 广播报文被截获,攻击者也无法解密报文数据。成功入网的MESH 设备会被分发一个网络密钥NetKey,可以根据该密钥接收、解密、中继该MESH 网络中的消息报文。

在一个SIG MESH 网络或子网内,一个设备节点几乎可以接收到该网络内传输的所有消息报文,但一个消息报文只想被其订阅者处理,而不想被无关设备节点获取正确的消息内容。为保证消息内容只能被其订阅者正确处理,需要对其再进行一层加密认证处理,订阅-发布属于应用层协议,因此可以将该层的加密认证密钥称为应用密钥AppKey。只有同一个主题的订阅者和发布者被分发相同的应用密钥AppKey,也即发布者先使用AppKey 对消息内容进行加密,再使用NetKey 对整个报文进行加密,只有被分发相同NetKey 的设备节点才能接收或中继消息报文,也只有被分发相同AppKey 的设备节点(也即该主题消息的订阅者)才能正确解密并处理报文中的消息内容,其余设备节点因没有对应的AppKey 而无法解密消息报文。
BLE 技术(七)--- BLE MESH 是如何设计的?
SIG MESH 设备节点之间的消息报文通过网络密钥NetKey 和应用密钥AppKey 认证加密可以保证消息报文的安全传输,NetKey 和AppKey 都是128 位的AES 对称加密密钥,采用AES-CCM 认证加密算法(AES-CTR 加密算法 + AES-CMAC 认证算法)来保证消息内容的机密性和完整性(后续BLE 版本可能会采用AES-GCM 认证加密算法)。网络密钥NetKey 和应用密钥AppKey 如何安全的分发呢?

2.2 启动配网与密钥分发

由于设备入网就需要凭借NetKey 和AppKey 接收并处理消息报文,这两个密钥的分发应该在设备入网阶段完成。将新的设备添加到BLE MESH 网络的过程跟LESC 配对过程也有点类似,大致可以分为下面几个过程:

  1. 邀请入网:要入网的设备会对外广播Mesh Beacon 报文,声明自己是未入网设备,可被启动配网设备Provisioner 发现。启动配网设备Provisioner 发现周围的Mesh Beacon 广播报文后,可以向其发送启动配网邀请报文(启动配网过程可以理解为入网过程),要入网的设备接收到Provisioning Invite 报文后回复一个包含自己支持的启动配网功能的报文Provisioning Capabilities(包括本设备支持的元素数量、支持的一组安全算法、是否支持OOB方式交换公钥、Input/Output 能力等信息);
    BLE 技术(七)--- BLE MESH 是如何设计的?
  2. 创建安全通道:启动配网设备Provisioner 和待入网设备New Device 之间通过BLE 或OOB 方式交换公共密钥,双方通过ECDH 椭圆曲线密钥协商算法生成共享密钥,并通过共享密钥加密后续的通信报文,相当于设备双方创建了一个安全通信链路;
    BLE 技术(七)--- BLE MESH 是如何设计的?
  3. 身份认证:为了防止攻击者伪装成New Device 入网获得NetKey 和AppKey,需要对入网的New Device 进行身份验证。TLS 是通过可信的第三方签名证书来验证通信对端的身份,BLE 作为近场通信协议,可以让配网的人参与验证入网设备的身份。根据待入网设备Input/Output 能力的不同,有Output OOB、Input OOB、Static OOB、No OOB 四种认证信息交换方法,比如New Device 是一个灯 - 用户观察其闪烁次数并输入Provisioner,再比如New Device 是一个开关 - 用户在一定时间内按压Provisioner 显示的次数,再比如New Device 是一个传感器 - 用户让Provisioner 获取该传感器指定的一个静态数值等(No OOB 相当于静态数值为0,这种方式容易被攻击者的伪装设备入网,不够安全,因此较少使用)。无论采用上述哪种认证信息交换方式,都需要根据双方获得的认证信息计算并生成确认值,当双方都通过确认值核对后(也即认证信息核对过程),New Device 通过身份认证,就可以分发密钥了,否则中止启动配网过程;
    BLE 技术(七)--- BLE MESH 是如何设计的?
  4. 分发密钥:Provisioner 与New Device 之间创建安全通信链路,且Provisioner 完成对New Device 的身份验证后,就可以向其分发MESH 网络需要的启动配网信息了,比如为New Device 每个元素分配的Unicast Address、接收并处理消息报文的NetKey / Appkey / Key Index / IV Index、验证后续配置者身份的DevKey(后续Provisioner 凭借DevKey 修改该device 的配置信息,若无对应的DevKey 则无法修改该设备配置)等。
    BLE 技术(七)--- BLE MESH 是如何设计的?

经过上述启动配网过程,入网设备被分发NetKey、Appkey、DevKey 等密钥,只要保证入网设备的身份没问题,密钥分发过程就是安全的。在上述身份认证环节,No OOB 认证信息交换方式是不安全的,可能会让攻击者伪装的New Device 成功入网,并获得被分发的密钥;其余三种认证信息交换方式是安全的,可以防止中间人攻击。

2.3 重放攻击与模糊化处理

BLE MESH 报文在网络中传输时,经过NetKey 认证加密,攻击者即便捕获了消息报文,也无法解密出报文中的消息内容。但攻击者可以先捕获该消息报文,在后面一个合适的时间点重新发送该消息报文,同样可以达到控制某个或某组设备的目的。比如捕获的报文是控制一组灯开启的,攻击者捕获该报文也不影响该报文正确送达其订阅者并被处理(泛洪广播可以多路径传播),在后面的某个时间点,攻击者重新发送该报文,是否也可以开启这组灯呢?

先捕获消息报文,在后面的某个时间点重新发送出去,达到模糊控制(因无法修改报文内容,没法做到精准控制)一组设备的攻击称为重放攻击或中继攻击。SIG 为了MESH 网络的安全性,肯定也设计了重放攻击防护方案,BLE MESH 是如何避免重放攻击的呢?

应对重放攻击,最直接的解决思路是让设备节点能识别每个消息报文,每个消息报文只处理一次,这样就可以忽略重放的消息报文。前面介绍受控泛洪广播寻址时也提到,为了减少泛洪广播对网络资源的消耗,控制每个设备节点对同一个数据包只处理一次,这也要求设备节点能识别相同的数据包,如何辨识每一个消息报文呢?

辨识每个消息报文,比较简单的方法是为每一个数据报文编号,也即在消息报文中增加序列号SEQ 字段(Sequence Number),且每个消息源(也即每个元素,由其单播地址标识)发出的消息报文要求SEQ 是严格递增的,SEQ 字段配合SRC 字段(Source Address,也即发送报文元素的Unicast Address)可以唯一标识该MESH 网络中的一个消息报文。每收到一个消息报文,设备节点会缓存该报文的SEQ 和SRC 字段信息,当再接收到与这两个字段相同信息的报文时忽略该报文,可以保证每个报文只处理一次,既降低了网络拥塞,又避免了被重放攻击。

SIG 设计MESH 协议时,要求每个消息报文的处理者(也即该消息的订阅者)接收同一数据源的消息报文SEQ 应该是严格递增的,也即只有当前接收报文的SEQ 大于前一个接收报文的SEQ,该消息报文才会被处理。由于SEQ 字段只有24 位,可标识的消息数量有限,当SEQ 超出可表示最大范围怎么办?

为了避免MESH 网络中,因SEQ 位数限制出现标识信息一致的消息报文,消息报文中还有一个IV Index 字段,该字段在设备入网时被分发,是全网共享的32 位数值,该值会在SEQ 增大到最大值前递增更新,因此 IV Index、SEQ、SRC 三个字段信息可以在整个MESH 网络存在期间唯一标识该网络中传输的每一个数据报文,且IV Index 和SEQ 是递增变化的。

设备入网后,消息报文都被网络密钥NetKey 加密了,MESH 网络层加密一般只加密有效载荷,网络层消息报文头部字段并没有被加密,攻击者还是可以捕获并读取消息报文的头部字段信息的。攻击者从报文头部可以获知该消息报文的LSB of IV Index、SEQ、SRC 等信息,这些信息是用来唯一标识消息报文的,如果明文传输,攻击者修改SEQ 字段后再发送出去,就可以让该消息的订阅者处理(依然满足SEQ 递增的要求),从而达到攻击的目的,甚至可以将SEQ 修改为一个很大的值,让该消息的订阅者忽略掉中间的很多消息。可见,MESH 网络层报文头部字段不能明文传输,该如何应对这种修改SEQ 的攻击呢?
BLE 技术(七)--- BLE MESH 是如何设计的?
既然MESH 网络层报文头部字段SEQ、SRC、TTL 等不能明文传输,也没有使用NetKey 进行加密处理,就需要采用其它的方式让攻击者无法读取并修改这些字段的内容。SIG 采用模糊混淆Obfuscation 方式让攻击者无法读取并修改SEQ、SRC、TTL 字段的信息,进行模糊混淆处理操作需要用到PrivacyKey,这个PrivacyKey 和Encryption Key 都是由入网时被分发的NetKey 生成的。

MESH 网络层报文有效载荷使用Encryption Key 认证加密,头部字段使用PrivacyKey 进行模糊混淆处理,报文的解密和去模糊化都需要NetKey。这样一来,攻击者即便捕获了消息报文,由于没有NetKey,也无法读取或修改报文信息,BLE MESH 也就达到了防止重放攻击的目的,同时也可以防止消息报文的传输被跟踪分析。

2.4 垃圾桶攻击与密钥刷新

前面的启动配网过程主要是将新设备加入现有MESH 网络,假如现有MESH 网络中的某个设备坏了或不需要了,可以直接扔了吗?

入网的设备都被分发了该MESH 网络的NetKey、AppKey 等密钥信息,如果从MESH 网络中移除的设备被攻击者获得,攻击者就可以读取其中的密钥信息,然后凭借这些密钥信息接收并处理该MESH 网络中的消息报文。由于被移除的设备通常是作为垃圾直接扔进垃圾桶了,攻击者从垃圾桶中获得MESH 网络的NetKey、AppKey 等密钥信息,因此这种攻击又称为垃圾桶攻击。SIG MESH 如何防护垃圾桶攻击呢?

要将一个在网的设备移除MESH 网络,通常需要执行下面两个步骤:

  • 加入黑名单:使用启动配网设备Provisioner 将要移除的设备节点添加进黑名单(需要持有该设备的DevKey 才能添加),当后续启动密钥刷新程序时,可以确保新的安全密钥不会被发放到黑名单中的设备节点;
  • 启动密钥刷新程序:启动密钥刷新程序后,启动配网设备Provisioner 会创建新的安全密钥,并通过配置消息报文向MESH 网络中除黑名单外的所有节点发送新的密钥(包括NetKey、AppKey、IV Index 等),保证MESH 网络和应用数据安全的整套密钥信息都会被替换。由于所有节点不会在同一时间接收到新密钥,密钥刷新程序定义了一个称为“第二阶段”的过渡期,在过渡期新旧密钥均可使用,过渡期后废除旧密钥。

经过上述从MESH 网络中移除设备节点的过程,被移除的节点中存储的旧密钥将失去作用,即便攻击者获得这些旧密钥,也无法接收或处理已执行过密钥刷新的MESH 网络消息报文。BLE MESH 应对垃圾桶攻击的重点是,被移除的设备节点需要按照上述流程处理,若用户移除在网设备后忘记执行上述流程,MESH 网络的安全性将无法得到保证。

三、BLE MESH 如何支持低功耗设备?

BLE MESH 网络采用受控泛洪广播方式传输数据报文,一个设备节点随时都有可能接收或者中继MESH 网络中的消息报文,因此不能像BLE Piconet 那样通过大部分时间睡眠达到低功耗的目的。

对于功耗不敏感的设备(比如电网供电的light)担任MESH 设备节点没问题,但对于功耗敏感的设备(比如电池供电的sensor)难以满足MESH 设备节点随时准备接收或中继消息报文的要求。SIG MESH 该如何支持低功耗设备节点的入网呢?

低功耗设备在MESH 网络中不能承担中继消息报文的角色,只能处于MESH 网络接收消息的边缘或末端节点。而且,低功耗节点需要有一个朋友节点配合,在其睡眠期间,帮其缓存消息报文。BLE MESH 网络拓扑结构图已经给出了Low Power Node 与Friend Node 在MESH 网络中的位置和关系了:
BLE 技术(七)--- BLE MESH 是如何设计的?
上图中黄色的节点是Low Power node,它们都通过Friend node 与MESH 网络进行消息报文的交互,也即Low Power 节点只与特定的Friend 节点通信。Low Power 节点是如何选择Friend 节点的呢?双方是如何建立Friendship 关系的呢?

首先,Low Power 节点为了尽可能节约能耗,减少射频发送或接收数据报文的时间,应该会与通信对象协调数据包发送和接收的时间窗口,也即Low Power 节点会告诉Friend 节点自己将在发出请求报文多久后(ReceiveDelay Time)开启射频接收器准备接收数据包,以及开启射频接收器用来接收数据包的时间窗口大小(ReceiveWindow Time),在ReceiveWindow 时间用完时便会再次sleep 以节省功耗。假如Friend 节点在一个ReceiveWindow 时间内无法将数据传输完毕怎么办呢?
BLE 技术(七)--- BLE MESH 是如何设计的?
Low Power 节点采用轮询方式向Friend 节点请求数据报文,每个轮询请求Friend Poll 报文后会在ReceiveDelay 事件后开启一个ReceiveWindow 用于接收Friend 节点发送的数据报文。如果数据较多则会分片发送,每个数据报文除了包含便于充足的序列号SEQ 外,还会包含一个MD 标识位用于标识是否还有后续报文需要传输。若MD 非0,则Low Power 节点会继续发送Friend Poll 报文,以便再开启一个ReceiveWindow 继续接受后续的数据报文,直到MD 为0,则表示本次数据接收完毕。

Low Power 节点与Friend 节点建立友谊后,周期性的向Friend 节点发送Friend Poll 报文(由于Friend 节点不知道Low Power 节点何时处于ReceiveWindow,因此只能由Low Power 节点周期性轮询是否有发给自己的消息报文,Friend 节点只有在接收到Friend Poll 报文后才能向Low Power 节点发送消息报文)查询是否有发送给自己的消息报文。Friend 节点为了及时了解Low Power 节点的活动状态,也会维护一个Poll Timer,每收到一个Friend Poll 报文会重置Poll Timer(超时值由Low Power 节点通过请求报文提供),当Poll Timer 触发超时仍未收到Friend Poll 报文,则判断Low Power 节点可能处于非活动状态,终止二者之间的Friendship 关系。

3.1 LPN与FN 如何建立Friendship?

Friend 节点实际上是启用了Friend 功能的MESH 普通节点,而且是已经过启动配网成功入网的MESH 节点。由于Friend 节点不知道Low Power 节点何时处于ReceiveWindow 时间(也即射频收发器transceiver 开启时间),友谊的建立过程由Low Power 节点发起请求,Friendship 建立过程大概需要下面几个步骤:
BLE 技术(七)--- BLE MESH 是如何设计的?

  • Friend Request:当Low Power 节点需要找一个Friend 节点,让其帮忙接收并缓存发给自己的消息报文时,需要先向周围发送Friend Request 消息报文(包含ReceiveDelay、ReceiveWindow、PollTimeout 等信息),该报文不会被中继,接收到该报文且支持“Friend” 特性的节点将会响应该请求报文;
  • Friend Offer:MESH 网络中支持“Friend” 特性的节点接收到Friend Request 消息报文后,将会向Low Power 节点回复一个Friend Offer 消息报文,该报文包含本节点支持的ReceiveWindow、MessageQueueSize、SubscriptionListSize、RSSI 等信息,供Low Power 节点根据自身需求选定附近的哪个节点作为自己的Friend 节点;
  • Friend Poll:Low Power 节点接收到周围多个节点发送来的Friend Offer 消息报文,根据Offer 报文中的信息通过特定算法选择合适的好友节点。比如有些LPN 会优先考虑ReceiveWindow 以尽可能节省功耗,有些LPN 则会优先考虑RSSI 以确保和FN 之间保持稳定可靠的通信链路等。Low Power 节点选定Friend 节点后,会向其发送Friend Poll 消息报文(其它发送Offer 节点的报文则不予理会);
  • Friend Update:Friend 节点接收到来自Low Power 节点的Friend Poll 消息报文后,向其回复一个Friend Update 消息报文,双方建立Friendship 关系。建立好友关系后,双方传输消息报文都通过friendship security material 进行加密,好友安全凭证是在双方建立好友关系过程中交互的LPNAddress、FriendAddress、LPNCounter、FriendCounter 等信息配合NetKey 计算出来的,且经过friendship security material 加密的消息报文只能由建立Friendship 关系的LPN 和FN 双方解密。

从上面Friendship 关系的建立过程可知,并没有对Low Power 节点的身份认证过程,所以建立好友关系的Low Power 节点和Friend 节点都是已经过启动配网过程,成功入网的MESH 节点。Low Power 节点和Friend 节点建立Friendship 关系过程发送的消息报文都使用Master security material(由NetKey 生成,可以理解为使用NetKey 加密) 加密,保证了MESH 网络通信的安全性。

前面介绍过,Low Power 节点与Friend 节点建立友谊后,会周期性的向Friend 节点发送Friend Poll 报文查询是否有发给自己的消息报文,若Friend 节点超过PollTimeout 都未收到Friend Poll 报文,则判断Low Power 节点可能处于非活动状态,终止二者之间的Friendship 关系。但若Friend 节点处于非活动状态了,Low Power 节点如何接收来自MESH 其它节点的消息报文呢?

Low Power 节点与Friend 节点建立友谊后,Friend 节点收到来自LPN 的Friend Poll 报文,即便暂时没有发给LPN 的消息报文,也会回复一个Friend Update 报文。如果Low Power 节点多次发送Friend Poll 报文均未收到对方回复的Friend Update 报文,则判断Friend 节点可能处于非活动状态,会重新向周围发送Friend Request 报文,尝试选择一个新的Friend 节点建立Friendship 关系。当新的Friendship 关系建立后,New Friend 节点会向Old Friend 节点发送Friend Clear 报文(包含Low Power 节点的单播地址信息)请求取消旧的Friendship 关系,待Old Friend 节点重新处于活动状态后,会收到来自New Friend 节点的Friend Clear 报文,终止Old Friendship 关系,并向New Friend 节点回复一个Friend Clear Confirm 报文。
BLE 技术(七)--- BLE MESH 是如何设计的?

3.2 LPN 与FN 如何传递消息?

Low Power 节点和Friend 节点建立起Friendship 关系后,Friend节点会为Low Power节点存储一个Friend Subscription List,该列表是Low Power节点订阅的单播地址、群组地址或虚拟地址的集合(Low Power 节点通过Friend Subscription List Add 报文告诉Friend 节点要添加哪些订阅地址,Friend 节点添加相应的订阅地址后向其回复一个Friend Subscription List Confirm 报文),表示Low Power节点想接收哪些节点发布的消息报文。
BLE 技术(七)--- BLE MESH 是如何设计的?

同时,Friend 节点还会为Low Power节点分配一个Friend Message Queue,用于存储待发送给Low Power 节点的消息报文,包括Low Power 节点订阅的消息报文、MESH 网络更新的安全参数(比如NetKey、IV Index)等。

当Friend 节点接收到来自Low Power节点的Friend Poll 报文后,会将Friend Message Queue 中暂存的消息报文发送给Low Power节点。如果需要发送的消息报文较多,会使用Friend Sequence Number 保证消息报文按顺序可靠传递。Friend Sequence Number 由Low Power节点在Friend Poll 报文中更新,若Friend Poll 报文中的FSN 未更新,则Friend 节点判断Low Power节点未收到上一个消息报文,会重新发送该消息报文。
BLE 技术(七)--- BLE MESH 是如何设计的?
Friend 节点为Low Power 节点缓存的消息报文,在接收到来自LPN 的Friend Poll 报文后,发送给Low Power 节点的报文使用friendship security material 进行加密,该报文只有持有同样安全密钥的Low Power 节点可以解密,同样保证了消息内容只能由其订阅者正确解密并处理的原则,有点类似于前面介绍的AppKey 的作用。

Low Power 节点发出的消息报文通常需要由其它节点中继转发,因此通常使用Master Security Material(由NetKey 生成)进行加密,也可由应用设置为使用friendship security material 进行加密,具体看应用需求。

四、BLE MESH 如何支持BLE GATT 设备?

BLE MESH 协议于2017 年才发布,BLE 协议则在2010 年就已经发布了,目前市面上支持BLE 协议的设备已经很多了,比如智能手机、平板电脑、无线传感器设备等。既然BLE MESH 协议是建立在BLE 协议之上的网络协议,二者共用BLE Controller 射频通信协议栈,能否通过OTA 升级让BLE 设备支持BLE MESH 协议,成为MESH 网络中的一个节点呢?

由于BLE MESH 协议需要额外占用一部分RAM 和Flash 资源,如果BLE 设备的RAM 和Flash 资源足够,是可以通过OTA 或有线升级的方式让其支持BLE MESH 协议的,比如手机或平板电脑可能只需要安装一个包含BLE MESH 协议的APP 就可以支持BLE MESH 协议了。但如果BLE 设备的RAM 或Flash 资源不足以升级BLE MESH 协议,怎么让这类BLE 设备接入MESH 网络或者与MESH 网络中的其它节点通信呢?

4.1 BLE GATT 设备如何收发MESH 消息?

回顾下同一网络中支持不同协议的设备间是如何通信的呢?常见的方式是设置网关,网关支持多种协议,在网关设备中完成不同协议报文的转换,从而让支持不同协议的设备间能够交互消息报文。BLE MESH 也支持这种类似网关的代理节点Proxy node,可以在BLE GATT 数据包和BLE MESH 数据包之间相互转换,借助Proxy node 就可以让BLE 设备通过GATT MESH Proxy Service 和BLE MESH 网络交互消息报文,Proxy 协议是如何设计的呢?

BLE Proxy node 同时支持BLE GATT 协议和BLE MESH 协议,在MESH 网络中作为支持“proxy” 特性的MESH node,在BLE Piconet 散点网中承担支持GATT MESH Proxy Service 的Proxy Server 的角色。
BLE 技术(七)--- BLE MESH 是如何设计的?
若BLE GATT 设备想收发BLE MESH 网络中的数据,需要作为GATT Client 角色(也即BLE Central / Master)扫描并连接Proxy Server(也即GATT Server 或BLE Peripheral / Slave,需要对外发送包含Mesh Proxy Service UUID 信息的可连接广播报文,以便周围的BLE Central / Master 扫描到)。

MESH Proxy node 为了支持收发GATT 报文,需要提供GATT Mesh Proxy Service,想收发MESH 消息的BLE GATT 设备连接Proxy Server 后,发现其提供的GATT Mesh Proxy Service,借助该服务提供的Mesh Proxy Data In Characteristic 和Mesh Proxy Data Out Characteristic (可以类比NUS 提供的NUS_Rx 和NUS_Tx Characteristic)就可以接收和发送MESH 消息报文了。
BLE 技术(七)--- BLE MESH 是如何设计的?
MESH Proxy Server 和BLE Proxy Client 之间的通讯是基于GATT 连接的,双方使用Proxy Protocol 定义的Proxy PDU (Attribute PDU 的Parameters 字段)交互MESH 消息报文。

MESH Proxy node 使用GATT 连接收发数据包使用的是GATT Bearer,在MESH 网络中使用Advertising 报文收发消息报文使用的是Advertising Bearer。因此,MESH Proxy node 要完成MESH 消息报文和GATT 数据包之间的转换,需要同时支持GATT Bearer (GATT Mesh Proxy Service 则需要ATT 和GATT 协议的支撑)和Advertising Bearer。
BLE 技术(七)--- BLE MESH 是如何设计的?

4.2 BLE MESH 如何保证与GATT 设备通信的安全?

BLE GATT 设备与MESH Proxy 节点建立BLE 连接后,通过GATT Mesh Proxy Service 在GATT 连接上传输被封装在Proxy PDU 中的MESH 消息报文,MESH 消息报文是被NetKey 加密的,BLE GATT 设备如果没有NetKey 是无法处理接收到的MESH 消息报文的,BLE GATT 设备如何获得NetKey、IV Index 等安全密钥呢?

BLE Proxy Client(也即BLE GATT Client 设备) 向MESH Proxy Server 发起并建立连接,并不要求双方执行安全配对过程。而且BLE MESH 要对入网的设备执行启动配网过程,由启动配网设备Provisioner 发起入网邀请 --> 创建安全通道 --> 完成身份认证 --> 分发安全密钥,BLE GATT 设备要收发MESH 消息报文,自然也算作MESH 网络中的一员,少不了执行启动配网过程。

BLE GATT 设备启动配网跟MESH 设备启动配网还是有区别的,BLE MESH 设备入网是通过Advertising Bearer 的PB-ADV(Provisioning Bearer - Advertising) 报文承载的启动配网信息,BLE GATT 设备不支持MESH Advertising Bearer,只好使用GATT Bearer 的PB-GATT(Provisioning Bearer - GATT) 报文来承载启动配网信息了。

类比MESH Proxy node 通过GATT Mesh Proxy Service 与BLE GATT 设备(Proxy Client)交互MESH 消息报文,要使用GATT 连接传输PB-GATT 报文,也需要启动配网设备Provisioner 提供相应的GATT Service 供GATT 设备发现并访问。SIG MESH为BLE GATT 设备启动配网提供的GATT Service 是Mesh Provisioning Service,也即启动配网设备Provisioner 需要支持GATT Bearer 并提供GATT Mesh Provisioning Service,才能为BLE GATT 设备发起启动配网邀请 --> 创建安全通道 --> 完成身份认证 --> 分发安全密钥。
BLE 技术(七)--- BLE MESH 是如何设计的?
GATT Mesh Provisioning Service 跟上面的GATT Mesh Proxy Service 类似,也提供了Mesh Provisioning Data In Characteristic 和Mesh Provisioning Data Out Characteristic,Provisioning Server 与Provisioning Client 之间也是通过Write Without Response 和Notifications 方式来访问GATT MESH Provisioning Data In/Out Characteristic 的,整个过程类比上面的GATT Mesh Proxy Service,这里就不赘述了。

基于PB-GATT 报文的启动配网过程和基于PB-ADV 报文的启动配网过程类似,可以参照前面介绍的启动配网过程理解,二者的差别只是封装Provisioning PDUs 报文的外壳不一样罢了。

4.3 BLE GATT 设备如何管理订阅列表?

BLE GATT 设备节点与Low Power 设备节点有点相似之处,二者都是BLE MESH 网络的边缘节点或末端节点,二者都需要借助MESH 网络中的另一个节点完成MESH 消息报文的收发(BLE GATT 节点需要借助MESH Proxy node 与MESH 网络其它节点通信,Low Power 节点则需要借助MESH Friend node 与MESH 网络其它节点通信)。

假如这里的BLE GATT 设备并非低功耗设备,倒是不需要MESH Proxy node 帮其缓存消息报文。MESH Proxy node 也需要为BLE GATT 设备维护一个订阅地址列表,以便知道MESH 网络中的哪些消息报文是发送给BLE GATT 设备的,没必要将收到的MESH 消息都发给BLE GATT 设备(既减少了GATT 链路的数据量,也增加了MESH 网络中的数据安全)。MESH Proxy node 如何为BLE GATT 设备维护订阅地址列表呢?

Friend 节点为Low Power节点维护一个存储一个Friend Subscription List,Low Power 节点通过Friend Subscription List Add 或Friend Subscription List Remove 报文向订阅列表中添加或移除地址。GATT 协议栈没有订阅列表之类的概念,倒是有过滤策略、白名单、黑名单之类的概念。

MESH Proxy node 则是为BLE GATT 节点维护了一个白名单和一个黑名单过滤列表,BLE GATT 节点(Proxy Client)通过Proxy configuration 消息报文(包含Set Filter Type、Add Addresses To Filter、Remove Addresses From Filter、Filter Status 等指令)向MESH Proxy node 维护的白名单或黑名单中添加或移除元素地址(可以是单播地址、组播地址、虚拟地址等)。
BLE 技术(七)--- BLE MESH 是如何设计的?
MESH Proxy node 会将MESH 消息中目的地址在白名单中的报文发送给BLE GATT 节点,将MESH 消息中目的地址在黑名单中的报文忽略。如果MESH 消息的目的地址不在白名单中,该MESH 消息报文也会被MESH Proxy node 的过滤策略滤掉。

更多文章:

上一篇:Uni-App开发BLE低功耗蓝牙流程


下一篇:蓝牙mesh、wifi、zigbee和lora、NB-lot区别和联系