零碎知识点:NRF52832配对与绑定问题

时间:2024-05-23 19:04:38

原文:https://blog.****.net/wenshifang/article/details/100038433

BLE的配对是一个比较繁琐的过程,需要熟悉规范,只有明白其中的原理才能更好的理解这个过程。
首先需要明确一点:配对的目的是为了加密通讯链路,保证数据安全,绑定是为了简化配对流程。

配对绑定过程说明:
1 配对信息的交换
2 生成STK(短期秘钥)加密链路
3 链路加密后就可以安全分发各种秘钥了,如果需要绑定,那么也会生成LTK(长期秘钥),双方都会存储LTK。
4 LTK分配之后,每次重新连接时双方用LTK与会话秘钥分散器等其他信息最终生成一个会话秘钥,真正的加密是用这个会话秘钥,其实这点也与大多数加密机制类似。

下面简单分析一下nrf协议栈中关于配对部分的流程。
在NRF52832(SDK 11.0 softdevice s132)中与链路安全相关的事件:
BLE_GAP_EVT_SEC_PARAMS_REQUEST
BLE_GAP_EVT_SEC_INFO_REQUEST
BLE_GAP_EVT_CONN_SEC_UPDATE
BLE_GAP_EVT_AUTH_STATUS

(1)在配对信息交换阶段,BLE_GAP_EVT_SEC_PARAMS_REQUEST事件会由协议栈上报给应用层:

零碎知识点:NRF52832配对与绑定问题

(2)在这个事件中,从机会把自己的信息与主机进行交换,其中就包含了从机的IO能力、配对完成是否绑定等(在sd_ble_gap_sec_params_reply第三个参数定义)信息。
1) 如果指定了从机具有显示能力,即BLE_GAP_IO_CAPS_DISPLAY_ONLY,那么调用sd_ble_gap_sec_params_reply后,应用层会收到BLE_GAP_EVT_PASSKEY_DISPLAY事件,从机将协议栈生成的随机密码显示到屏幕即可,此时主机也会出现一个配对框,用户输入从机显示的密码即可完成配对。若从机没有输出能力,那么可以指定为BLE_GAP_IO_CAPS_NONE,此时主机不再要求输入密码,而是询问是否同意配对。若密码匹配或用户同意配对,那么配对过程继续,直到协议栈上报BLE_GAP_EVT_CONN_SEC_UPDATE事件代表配对成功:

零碎知识点:NRF52832配对与绑定问题

 

2.如果指定配对完成后绑定,那么协议栈会进行LTK的分发,秘钥分发完成后,协议栈会上报BLE_GAP_EVT_AUTH_STATUS事件表示:

零碎知识点:NRF52832配对与绑定问题

(3)LTK分发完成后,从机可以将协议栈返回相关秘钥信息保存下来:

零碎知识点:NRF52832配对与绑定问题

至此整个配对绑定过程完成。
下面再分析一下,当链路重新建立时的情况。
上面提到,绑定操作是为了简化配对流程。当双方都保存有配对信息时(最重要的是LTK),可以直接使用LTK参与会话秘钥的生成,一般情况下,主机会发起加密请求,从机会响应加密请求,在nrf协议栈中,相关事件是BLE_GAP_EVT_SEC_INFO_REQUEST:

零碎知识点:NRF52832配对与绑定问题

收到BLE_GAP_EVT_SEC_INFO_REQUEST事件后,从机会查询本地有没有当前连接的主机相关秘钥信息,并把查询结果传递到协议栈给主机回应。那么到底是以什么作为匹配标准来查询这个秘钥信息呢,首先想到的是主机的MAC,没错,确实是MAC地址,但是除了MAC地址,还有一项diversifier(分散器),记为EDIV:

零碎知识点:NRF52832配对与绑定问题

如果单单是MAC地址,就无法解释iOS系统Private Non-Resolvable address的现象:iOS每次重启系统或重启蓝牙,BLE的MAC地址都会被改变,话说是为了防止设备被追踪。
diversifier的值由发起配对的一方传送,接收的一端进行匹配,除了diversifier之外,还有随机数Rand、初始向量IV等与加密相关的参数随着加密请求LL_Encryption Req发送给对方。
一旦匹配成功,后续通讯链路就可以进入加密状态,下面是通过空中抓包关于主机发起加密的过程:

零碎知识点:NRF52832配对与绑定问题

可以看到,在M->S的加密请求包中,包含了4个域,都是与加密相关的字段,其中一项就是EDIV,随后S->M的加密响应中,从机向主机传送了自己的STK和IV,主从双方准备好之后,从机发起开始加密请求,在随后的数据包中,协议分析软件显示多了一项Security_Enabled,可知链路已进入了加密状态。

如若一切顺利,上述过程没有什么问题,一旦一个环节出错,配对就无法完成了。例如当从机保存的配对信息失效了(一般会保存在Flash中,Flash并不是百分之百可靠),就无法再正确的进行链路加密。
在我的这个案例中,从机是nrf52832,主机是iOS系统,业务流程简单:
从机通过用户app配对完成后,可以脱离app而独立工作,并接收ANCS消息。
在测试过程中发现,主机在断线后(时间和次数不确定),不再主动连接从机,手动连接从机后,ANCS通知也不正常,并且再次断线后也不会回连。

经过无数次的问度娘,也没有找到相关的问题,最后无奈,只能使出杀手锏:通过抓包分析

零碎知识点:NRF52832配对与绑定问题

可以看到,主机在连接上从机后与从机交换了协议版本信息,接着就发送了一条加密请求,要求从机进行链路加密,后面的数据包中,我们看到从机第二次回应时,发送了一个LL_Reject_Rsp,一开始不知道这个包的含义,但是Reject明显不是什么好事,对比正常的响应包,此处应该是Start_Encryption Req才对,经过多次实验得知,iOS系统在5次重连发加密请求都收到LL_Reject_Rsp时,就不会再回连该从机(目前还没找到apple相关资源), 那么,我的思路就是在从机查找不到主机的配对信息时,向主机发起配对请求,要求用户重新确认并配对。

零碎知识点:NRF52832配对与绑定问题

零碎知识点:NRF52832配对与绑定问题

核心操作就在dm模块:dm_security_setup_req(),向主机发起配对请求。
这个方案基本上可以解决这个问题,但如果用户没有来得及产看手机并确认配对,且重连次数连续超过5次,系统还是会停止回连从机。