凡亿教育-江江
凡事用心,一起进步
打开APP
公司名片
凡亿专栏 | 从0开始学习BLE:BLE配对和绑定实例分析
从0开始学习BLE:BLE配对和绑定实例分析

e560047713cee09745398a81b60ad5.jpg

BLE架构图在文章标题中我们多次引用这份架构图,只因为这份图实在是太重要了,但是对于初学者来说可能理解不了,还是希望大家多看看这张图,尤其是学习协议理论上的知识的时候。话不多说,今天我们要分析的是BLE的配对和绑定过程。简单来说配对就是密钥交换的过程,绑定就是存储密钥的过程。

一,协议层面首先对协议做下回顾,广播就不讲了,讲的地方太多了,咱们直接从数据包开始。数据包的结构如下:3ecf5e112c901ffbb8797a5267c980.jpg

数据包

b44579a8c8bca891f7c991d6caea13.jpg

数据包PDU

acd6a4cdf46c14a16f302c45ec7399.jpg

数据包PDU包头数据包的PDU的头部的LLID,这是区分包的用途的主要标识。LLID:(Logical Link Identifier),信道标识符

00 表示为保留;


01表示为链路层数据PDU,传输到上层的数据且L2CAP消息是连续分段或空的PDU;


10 表示为链路层数据PDU,传输到上层的数据且L2CAP消息的起始或未分段的完整I2CAP消息


11表示为链路层控制包,链路层完成控制



LLID=0x10时报文结构

5c138cfbd326d492cb7d946a26dc13.jpg

信道ID:CID(Channel Identifier)
f159d72336ad8a46cc2412c746dd99.jpg

CID=0x06 表示数据是传输到安全管理协议层的数据
4284b64b617b09a78bcb505e38c717.jpg

SMP层包结构

CID=0x06后面紧SMP层的操作码

ad4aa8ab6ac9c129de6e8799952493.jpg

SMP层操作码

接下来我们看下绑定的通信过程

4e4064e9ebf26a576d2c92eca454d8.jpg全部SMP通信过程数据接下来我们一条一条的解读一下。第1条数据包e0a100044ce2f046eeec2729b1b21b.jpg

操作码 Opcode=0x01 配对请求

3eab4e6d942078b173ea72e1009e25.jpg

当设备需要建立安全连接(如读写加密特征、绑定设备)时,由主设备主动发送。要传递的信息包含以下关于配对的信息说明。

1,自己的IO能力

2,OOB能力

3,请求的加密的属性设置

4,密钥长度

5,主设备可以分发密钥的类型有哪些

6,请求从设备可以分发的密钥类型有哪些

117399a7a1fd42b02b257e9ebab15e.jpg


IO能力

IO能力说明自己是否包含键盘、显示器之类的人机交互设备,以便于输入或者显示配对码。bbbaf32f53103deb013524d2c498e4.jpg


OOB标识

是否具有其他非无线的方式传递密钥信息,称为“带外”OOB。e1ca0d783ab6a4b53f9fbfea03081c.jpg

请求的安全属性


Bonding_Flags:交换密钥后是否存储密钥信息。

MITM:设备请求MITM(防中间人攻击)。

SC:设备是否支持LE安全配对。


Keypress:仅在密钥输入协议中使用,双方都为1,将生成按键通知。


第2条数据包

操作码 Opcode=0x02 配对响应

017ac2e35ef3fb6abdef42ba62ec2e.jpg

同样的从机也向主机表明自己的能力第3条数据包 

操作码 Opcode=0x0C 配对公钥分发

6075ed0a821c675e256c2e8349f336.jpgafe6e37824db2167e40c6efae2f1a2.jpg

精髓来了:

32字节的X坐标和32字节的Y坐标构成了公钥(基于椭圆曲线)。


6bb679051a51ecb249827a99d94156.jpg

1,公钥和私钥是具有一定关系,并不是完全独立的。


2,双方虽然不知道彼此的私钥,通过用自己的私钥和对方发来的公钥进行运算可以得到DHKey,另一方同样的可以得到一个密钥DHKey,而这个DHKey双方是相同的,然后用DHKey进行初步加密和进行后续的密钥计算。


通过上面的公钥交换,双方得到了同一个密钥,而第三方又不知道这个密钥,有没有觉得那些牛逼的数学家就是个天才。第4条数据包 

操作码 Opcode=0x0C 配对公钥分发

e824b60baceea35d11a30f29a1ad6a.jpg从机也向主机发送自己的公钥,主机计算自己的DHKey。第5条数据包 

操作码 Opcode=0x03 配对确认

4eb5b3e5e56b4445a55193abfb74a5.jpg232d4c3b0c7f341be264f2e513aa55.jpg

发送确认值,确认值通过以下方式计算得出

Confirm Value = f4(DHKey || RandomValue || Address || Other parameters)


e582a27294df907bed75cc38f94685.jpg

关于这个公式是什么,你只要知道f4是一个公式,经过这个公式计算后的数据是和后面括号里的参数唯一对应即可。

正常的配对过程应该是:
主机发送随机数(0x04),接着从机发送随机数(0x04),从机发送确认值(0x03),然后双方根据这些信息计算并验证确认值。

这样双方拥有相同DHKey、主机随机数、从机随机数,计算出来的确认码一致。

但是我不知道为什么nordic的协议栈会先发送确认值,然后才进行了随机数的交换,难道是没有使用随机数计算确认值?有知道朋友欢迎评论区交流。

第6条数据包 

操作码 Opcode=0x04 发送随机数

cddbd849dc85572b97663fe482bd3a.jpg61aaf03e6ec8f82ada06dd16f2571d.jpg

经过交换


从机拥有:自己的随机数,主机的随机数,共享密钥,自己生成的确认码


主机拥有:自己的随机数,从机的随机数,共享密钥,从机生成的确认码


主机就可以通过


Confirm Value = f4(DHKey || RandomValue || Address || Other Parameters)


计算确认码和从机传送的确认码是否一致。


一旦双方成功通过DHKey Check,就说明两边:


    拥有相同的Diffie-Hellman Key(DHKey)


    使用了相同的输入参数(Na、Nb、r、IOcap 等)


    没有中间人篡改或攻击


接下来,双方会使用如下公式来生成会话加密密钥(LTK,Long Term Key)


LTK = f5(DHKey, Na, Nb, A1, A2)

b3858426a74486cde11ee70b0120ce.jpg第7条数据包 

操作码 Opcode=0x04 发送随机数

d39fbbef93958d8d5c770164fd70bc.jpg

正常应该是先交换双方的随机数才对啊。

第8条数据包 

操作码 Opcode=0x0d DHKey校验

5058bae94c0179a3f71a0f1b351ac9.jpg

这里校验码由以下信息生成E = f6(MacKey, Na, Nb, r, IOcap, A1, A2)8748390c2d10d82b3c62bfa881b8f5.jpg

验证配对过程中的关键参数没有被篡改。第9条数据包 主机重复发送0x0d第10条数据包 

操作码 Opcode=0x0d DHKey校验

e3b53b671e10eebd4c845598184bb9.jpg从机也向主机发送自己的校验码双方校验完成以后,即验证了双方加密信息的一致性,其他密钥直接通过DHKey派生而来。根据加密方式的不同,后续可能进行密钥交换,nordic没有这个步骤,后续直接开启了链路加密。6eaf9c37d561f08fda6018a147c2e8.jpg第11条数据包 

操作码 Opcode=0x05 配对失败

af36d9213d08ea4192caf19eaf1899.jpgb2287b0b009ad581a4ab6a43c30685.jpg08971e84dcacba455de847a4a135c6.jpg

当然当你配对发生异常的时候,对端会发送一个0x05操作码的指令告诉你配对失败的原因。我使用官方心率例程的时候,第一次配对成功后,下次再次点击配对,那么回复的就是0x05配对码的0x05号原因。即使手机上删除绑定信息,依然不能再次绑定,除非擦除芯片后重新烧录程序。大概是因为设备端没有做删除密钥的操作,这个问题我们后续再研究。拿nordic代码举例

跟没有paring的ble应用代码相比,有paring的ble应用只多了一个初始化函数:peer_manager_init(),peer_manager_init实现代码如下所示:

8dd2c31213cb0e5bf455f00a8ea9ea.jpg

peer_manager_init里面注册了一个回调函数:pm_evt_handler,用来添加一些用户自定义的处理,例子代码pm_evt_handler的实现如下所示:

25593db734857c02c174a22f927b41.jpg

至此,一个just works的蓝牙配对例子就算完成了。

也就是我们只对加密提出了一些要求,进行了简单的配置,其他的工作全部是由协议栈完成的,所以你从代码里也找不到密钥,密钥是有协议栈生成的。

希望通过以上的介绍,大家能对神秘的配对过程不再感到那么神秘。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论