概述
配网(Provisioning)流程属于蓝牙Mesh网络中的重要一环,正是通过配网流程,才使得蓝牙Mesh设备(Device)变成网络中的一个节点(Node),因此,本文将着重讲解配网流程及其相关概念,希望能够给读者以清晰的理解。
名词解释
- 设备(Device)表示处于未配网的实体。
- 节点(Node)表示当前已经处于配网状态的实体。
- 配网者(Provisioner)表示具备将其他设备通过配网流程让其成为节点的功能的实体。
配网流程
1、设备发送PB-ADV的广播
如果设备支持PB-ADV配网,也就是如果设备支持通过广播方式配网的话,其必须发送Unprovisioned Device Beacon,在笔者书写时,远程配网还未在正式规范中,因此配置者必须处在设备的广播范围内(Single Hop)。设备发送的Unprovisoned Device Beacon 包含该设备的UUID用于唯一标识该设备,包含设备的OOB信息用于描述公钥传输方式,例如:NFC、二维码等,包括可选的URI信息(用于标识设备,例设备的类型、图像等),这些信息将在后续步骤中使用。
2、设备发送PB-GATT的广播
如果设备支持PB-GATT配网,也就是说设备支持通过连接方式配网的话,其必须发送可连接的广播报文,其发送的广播信息同样包括了设备UUID以及设备的OOB信息。注意:如果设备同时支持两种配网方式,必须交叉发送这两种广播报文。
3、配置者发送邀请
首先需要说清的时,只有收到的配网广播类型与配置者支持PB-ADV或者PB-GATT方式配网能力一致才能进行,也就是说,只支持PB-GATT(大部分的智能手机就是这种)方式的配置者不能通过PB-ADV方式配网设备,即使配置者能够收到PB-ADV的广播,反之亦然。
配置者在收到相对应的未配置广播后,会发送配置邀请(Provision Invite)让设备进入配网状态。但是由于PB-ADV与PB-GATT的数据传输方式不一致,因此通过PB-ADV方式的配网流程整体复杂度要高与通过连接方式的,限于篇幅,本文将不再详述,感兴趣的读者自行看规范(Mesh Profile 1.0.1 Section 5 Provisioning)。
4、设备发送配置能力
设备端在收到来自配置者发送的配置邀请后,会将自身的输入输出能力通过配置能力(Provision Capability)发送给配置者作为响应。这种描述设备的输入输出能力将会直接影响后续的配置流程。值得一提的是,配置能力包括设备端是否具备公钥信息带外传输能力(Public Key OOB Information),这种信息与设备在步骤1、步骤2中发送的OOB相呼应,还包括设备是否支持静态认证信息(Static OOB Information),也就是固定的认证值(双方都必须对应一致的存放才能使用),还包括输入输出能力(Input Output OOB Information),最后包括一个描述设备中元素(Element)多少的信息,综上,这些信息都将传给配置者。
5、配置者发送配置开始
配置者在收到来自设备发送的配置能力后,需要根据自身与设备的输入输出能力决定合适的配置算法来进行安全的认证。例如:配置者会检查设备与其自身是否都支持公钥带外传输能力,如果都支持,配置者可以选择这种方式(OOB Public Key)进行公钥传输,例如:通过二维码扫描或者NFC读取等,否则公钥将通过配网流程(No OOB Public Key)传输(这种方式的安全级别当然低于上面的方式)。接着配置者会检查双方输入输出能力,如果设备支持输入,配置者有能力输出的话,可以使用方式(Input OOB authentication)进行安全认证,如果设备支持输出,配置者有能力输入的话,可以使用方式(Output OOB authentication)进行安全认证,如果设备支持静态认证,配置者同样支持静态认证,可以使用方式(Static OOB authentication)进行安全认证。最后如果设备与配置者都没有合适的输入输出相呼应,只能通过非安全认证(No OOB authentication)。
根据公钥带外传输能力,后续公钥传输可以分为
-
A1 No OOB Public Key is used
-
A2 OOB Public Key is used
根据输入输出能力,后续认证算法可以分为:
-
B1 No OOB authentication is used
-
B2 Static OOB authentication is used
-
B3 Output OOB authentication is used
-
B4 Input OOB authentication is used
后续配置流程将根据配置者的选择进行,可能存在的路线有:
A
1
B
1
、
A
1
B
2
、
A
1
B
3
、
A
1
B
4
、
A
2
B
1
、
A
2
B
2
、
A
2
B
3
、
A
2
B
4
A1B1、A1B2、A1B3、A1B4、A2B1、A2B2、A2B3、A2B4
A1B1、A1B2、A1B3、A1B4、A2B1、A2B2、A2B3、A2B4
6、配置者发送公钥(A1)
如果配置者在步骤5选择公钥非带外传输的话,那么在配置者发送完配置开始后,紧跟着发送配置者公钥(Provisoner Public Key)。注意:公钥与私钥应当在每次配网流程中都必须重新生成。
7、配置者发送公钥(A2)
如果配置者在步骤5选择公钥带外传输的话,其在发送配置开始后,必须通过步骤1或步骤2中OOB信息所描述的方式(NFC、二维码等)来获取设备端公钥(Device Public Key)。
8、设备发送公钥(A1)
如果设备端在步骤5收到来自配置者选择的公钥非带外传输后将执行此步骤,其必须等待步骤6配置者发送配置者公钥后,发送设备公钥(Provisioning Device Public Key)。
9、配置者发送确认值(B1、B2、B4)
当配置者在步骤6后,应该等待步骤8设备端公钥,或者当配置者在步骤7后,开始执行生成随机数(RandomProvisioner )并根据收到的来自设备端公钥生成ECDHSecret:
E
C
D
H
S
e
c
r
e
t
=
P
−
256
(
p
r
i
v
a
t
e
k
e
y
,
p
e
e
r
p
u
b
l
i
c
k
e
y
)
ECDHSecret = P-256(private key, peer public key)
ECDHSecret=P−256(privatekey,peerpublickey)
确认值(Confirm)的生成应根据:
如果配置者选择的算法是非安全认证B1
A
E
S
−
C
M
A
C
C
o
n
f
i
r
m
a
t
i
o
n
K
e
y
(
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
0
x
00
)
AES-CMACConfirmationKey (RandomProvisioner || 0x00)
AES−CMACConfirmationKey(RandomProvisioner∣∣0x00)
如果配置者选择的算法是静态安全认证B2
A
E
S
−
C
M
A
C
C
o
n
f
i
r
m
a
t
i
o
n
K
e
y
(
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
S
t
a
t
i
c
K
e
y
)
AES-CMACConfirmationKey (RandomProvisioner || Static Key)
AES−CMACConfirmationKey(RandomProvisioner∣∣StaticKey)
如果配置者选择的算法是输出安全认证B4,配置者应当根据设备显示的Auth Value
A
E
S
−
C
M
A
C
C
o
n
f
i
r
m
a
t
i
o
n
K
e
y
(
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
A
u
t
h
V
a
l
u
e
)
AES-CMACConfirmationKey (RandomProvisioner || Auth Value)
AES−CMACConfirmationKey(RandomProvisioner∣∣AuthValue)
10、配置者发送确认值(B3)
在步骤6后,应该等待步骤8设备端公钥,或者当配置者在步骤7后,开始执行生成随机数(RandomProvisioner )以及随机化(Auth Value)并通过步骤5协商的输出方式输出出来,并根据收到的来自设备端公钥生成ECDHSecret:
E
C
D
H
S
e
c
r
e
t
=
P
−
256
(
p
r
i
v
a
t
e
k
e
y
,
p
e
e
r
p
u
b
l
i
c
k
e
y
)
ECDHSecret = P-256(private key, peer public key)
ECDHSecret=P−256(privatekey,peerpublickey)
确认值(Confirm)的生成应根据:
A
E
S
−
C
M
A
C
C
o
n
f
i
r
m
a
t
i
o
n
K
e
y
(
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
A
u
t
h
V
a
l
u
e
)
AES-CMACConfirmationKey (RandomProvisioner || Auth Value)
AES−CMACConfirmationKey(RandomProvisioner∣∣AuthValue)
配置者应当等待来自步骤11的输入完成(Provision Input Complete)后,发送确认值(Confirm)。
11、设备发送输入完成(B3)
在步骤6或步骤7后,开始执行生成随机数(RandomDevice)并根据收到的来自设备端公钥生成ECDHSecret:
E
C
D
H
S
e
c
r
e
t
=
P
−
256
(
p
r
i
v
a
t
e
k
e
y
,
p
e
e
r
p
u
b
l
i
c
k
e
y
)
ECDHSecret = P-256(private key, peer public key)
ECDHSecret=P−256(privatekey,peerpublickey)
设备端应当根据配置者显示的Auth Value ,应当在设备端确认值生成后发送输入完成,其中确认值(Confirm)的生成应根据:
A
E
S
−
C
M
A
C
C
o
n
f
i
r
m
a
t
i
o
n
K
e
y
(
R
a
n
d
o
m
D
e
v
i
c
e
∣
∣
A
u
t
h
V
a
l
u
e
)
AES-CMACConfirmationKey (RandomDevice || Auth Value)
AES−CMACConfirmationKey(RandomDevice∣∣AuthValue)
12、设备发送确认值
设备端收到来自配置者的确认值后,应当发送设备端确认值。
13、配置者发送随机数
配置者收到来自设备端的确认值后,应当发送配置者随机数(RandomProvisioner)。
14、设备发送随机数
设备端收到来自配置者的随机数后,应当与之前收到的来自配置者确认值进行校验,如果匹配,应当发送设备端随机数(RandomDevice),并根据随机数生成Device Key:
D
e
v
K
e
y
=
k
1
(
E
C
D
H
S
e
c
r
e
t
,
P
r
o
v
i
s
i
o
n
i
n
g
S
a
l
t
,
“
p
r
d
k
”
)
DevKey = k1(ECDHSecret, ProvisioningSalt, “prdk”)
DevKey=k1(ECDHSecret,ProvisioningSalt,“prdk”)
其中 ProvisioningSalt应当:
P
r
o
v
i
s
i
o
n
i
n
g
S
a
l
t
=
s
1
(
C
o
n
f
i
r
m
a
t
i
o
n
S
a
l
t
∣
∣
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
R
a
n
d
o
m
D
e
v
i
c
e
)
ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)
ProvisioningSalt=s1(ConfirmationSalt∣∣RandomProvisioner∣∣RandomDevice)
15、配置者发送配置数据
配置者收到来自设备端的随机数后,应当与之前收到的来自设备端确认值进行校验,如果匹配,应当发送配置数据(Provision Data)。
其中配置数据包括:
- Network Key 配置者分发的网络层的密钥。
- Network Index 配置者分发的网络密钥索引(其中0x0000为主网,其余为次网)。
- Key Reflash Flag 当前的网络密钥更新状态。
- IV Update Flag 当前的IV Index更新状态。
- IV Index 当前的IV Index值。
- Primary Address 配置者分发给设备的主地址。
注意此数据包通过之前协商的数据进行加密:
P
r
o
v
i
s
i
o
n
i
n
g
S
a
l
t
=
s
1
(
C
o
n
f
i
r
m
a
t
i
o
n
S
a
l
t
∣
∣
R
a
n
d
o
m
P
r
o
v
i
s
i
o
n
e
r
∣
∣
R
a
n
d
o
m
D
e
v
i
c
e
)
ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)
ProvisioningSalt=s1(ConfirmationSalt∣∣RandomProvisioner∣∣RandomDevice)
S
e
s
s
i
o
n
K
e
y
=
k
1
(
E
C
D
H
S
e
c
r
e
t
,
P
r
o
v
i
s
i
o
n
i
n
g
S
a
l
t
,
“
p
r
s
k
”
)
SessionKey = k1(ECDHSecret, ProvisioningSalt, “prsk”)
SessionKey=k1(ECDHSecret,ProvisioningSalt,“prsk”)
S
e
s
s
i
o
n
N
o
n
c
e
=
k
1
(
E
C
D
H
S
e
c
r
e
t
,
P
r
o
v
i
s
i
o
n
i
n
g
S
a
l
t
,
“
p
r
s
n
”
)
SessionNonce = k1(ECDHSecret, ProvisioningSalt, “prsn”)
SessionNonce=k1(ECDHSecret,ProvisioningSalt,“prsn”)
配置数据原始报文为:
P
r
o
v
i
s
i
o
n
i
n
g
D
a
t
a
=
N
e
t
w
o
r
k
K
e
y
∣
∣
K
e
y
I
n
d
e
x
∣
∣
F
l
a
g
s
∣
∣
I
V
I
n
d
e
x
∣
∣
U
n
i
c
a
s
t
A
d
d
r
e
s
s
Provisioning Data = Network Key || Key Index || Flags || IV Index || Unicast Address
ProvisioningData=NetworkKey∣∣KeyIndex∣∣Flags∣∣IVIndex∣∣UnicastAddress
加密后的数据应当为:
A
E
S
−
C
C
M
(
S
e
s
s
i
o
n
K
e
y
,
S
e
s
s
i
o
n
N
o
n
c
e
,
P
r
o
v
i
s
i
o
n
i
n
g
D
a
t
a
)
AES-CCM (SessionKey, SessionNonce,Provisioning Data)
AES−CCM(SessionKey,SessionNonce,ProvisioningData)
16、设备发送配置完成
设备在收到来自配置者发送配置数据并成功解密后,应当发送配置完成(Provision Complete),至此,当前设备已经变成网络中的一个节点。