应用

技术

物联网世界 >> 物联网新闻 >> 物联网热点新闻
企业注册个人注册登录

科普 | 低功耗蓝牙配对

2020-06-04 08:49 互联网
关键词:低功耗蓝牙

导读:什么是低功耗蓝牙配对?什么又是绑定?配对和绑定有什么区别?配对有什么好处?如何删除绑定信息?如何确定配对的安全等级?just work 的配对一定就不安全吗?如何开发自己的配对应用?本文将对以上问题进行论述。

Paring(配对)和 bonding(绑定)是实现蓝牙射频通信安全的一种机制,有两点需要注意:

一是 paring/bonding 实现的是蓝牙链路层的安全,对应用来说完全透明,也就是说,不管有没有 paring/bonding,你发送或接收应用数据的方式是一样的,不会因为加了 paring/bonding 应用数据传输需要做某些特殊处理;

二安全有两种选项:加密或者签名,目前绝大多数应用都是选择加密,后续我们也会以加密为重点进行讲述

实现蓝牙通信安全,除了 paring/bonding 这种底层方式,用户也可以在应用层去实现相同功能,两者从功能上和安全性上没有本质区别,只不过应用层自己实现的话,需要自己选择密码算法,密钥生成,密钥交换等,如果你不是这方面的专家,你的应用就有可能会存在安全漏洞。Paring/bonding 则把上述过程标准化,放在了蓝牙协议栈中,并且其安全性得到了充分评估,用户可以 “无感的” 用上安全的蓝牙通信。

Paring/bonding 是蓝牙 security manager(SM)的一部分,SM 定义了蓝牙通信的安全框架,里面涉及安全架构,密码工具箱,paring 协议等,其中 paring 协议是关键,所以我们经常把 paring 和 SM 二者等价,下面将对 paring 进行详细阐述。

1、基本概念解读

°Paring(配对)

配对包括配对能力交换,设备认证,密钥生成,连接加密以及机密信息分发等过程,配对的目的有三个:加密连接,认证设备,以及生成密钥。从手机角度看,一旦设备跟手机配对成功,蓝牙配置菜单将包含该配对设备,如下所示:

如果用户需要主动删除配对设备,点击配对设备右边的“设置”菜单,出现如下界面,选择“取消配对”或者“忽略该设备”,设备的配对信息即被手机删除。

°

Bonding(绑定)

配对过程中会生成一个长期密钥(LTK,long-term Key),如果配对双方把这个 LTK 存储起来放在 Flash 中,那么这两个设备再次重连的时候,就可以跳过配对流程,而直接使用 LTK 对蓝牙连接进行加密,设备的这种状态称为 bonding。

如果 paring 过程中不存储 LTK(不分发 LTK)也是可以的,paring 完成后连接也是加密的,但是如果两个设备再次重连,那么就需要重走一次 paring 流程,否则两者还是明文通信。

在不引起误解的情况下,我们经常把 paring 当成 paring 和 bonding 两者的组合,因为只 paring 不 bonding 的应用情况非常少见。在不引起混淆的情况下,下文就不区分 paring 和 bonding 的区别,换句话说,我们会把 paring 和 bonding 两个概念等同起来进行混用。

°SM(security manager)

蓝牙协议栈的安全管理层,规定了跟蓝牙安全通信有关的所有要素,包括 paring,bonding,以及下文提到的 SMP。

°SMP(security manager protocol)

安全管理协议,SMP 着重两个设备之间的蓝牙交互命令序列,对 paring 的空中包进行了严格时序规定。

°OOB(out of band,带外)

OOB 就是不通过蓝牙射频本身来交互,而是通过比如人眼,NFC,UART 等带外方式来交互配对信息,在这里人眼,NFC,UART 通信方式就被称为 OOB 通信方式。

°Passkey

又称 pin 码,是指用户在键盘中输入的一串数字,以达到认证设备的目的。低功耗蓝牙的 passkey 必须为 6 位。

°Numeric comparison(数字比较)

Numeric comparison 其实跟 passkey 一样,也是用来认证设备的,只不过 passkey 是通过键盘输入的,而 numeric comparison 是显示在显示器上的,numeric comparison 也必须是 6 位的数字。

°MITM(man in the middle)

MITM 是指 A 和 B 通信过程中,C 会插入进来以模拟 A 或者 B,并且具备截获和篡改 A 和 B 之间所有通信报文的能力,从而达到让 A 或者 B 信任它,以至于错把 C 当成 B 或者 A 来通信。

如果对安全要求比较高,需要具备 MITM 保护能力,在 SM 中这个是通过认证(authentication)来实现的,SM 中实现认证的方式有三种:OOB 认证信息,passkey 以及 numeric comparison,大家根据自己的实际情况,选择其中一种即可。

°LESC(LE secure connections)

又称 SC,蓝牙 4.2 引入的一种新的密钥生成方式和验证方式,SC 通过基于椭圆曲线的 Diffie-Hellman 密钥交换算法来生成设备 A 和 B 的共享密钥,此密钥生成过程中需要用到公私钥对,以及其他的密码算法库。

LESC 同时还规定了相应的通信协议以生成该密钥,并验证该密钥。需要注意的是 LESC 对 paring 的其他方面也会产生一定的影响,所以我们经常会把 LESC 看成是一种新的配对方式。

°Legacy paring

在 LESC 引入之前的密钥生成方式,称为 legacy paring,换句话说,legacy paring 是相对 LESC 来说的,不支持 LESC 的配对即为 legacy paring(legacy 配对)。

°TK(Temporary Key,临时密钥)

legacy paring 里面的概念,如果采用 just work 配对方式,TK 就是为全 0;如果采用 passkey 配对方式,TK 就是 passkey;如果采用 OOB 配对方式,TK 就是 OOB 里面的信息。

°STK(short term key,短期密钥)

legacy 配对里面的概念,STK 是通过 TK 推导出来的,通过 TK 对设备 A 和 B 的随机数进行加密,即得到 STK。

°LTK(long term key,长期密钥)

legacy 配对和 LESC 配对都会用到 LTK,如前所述,LTK 是用来对未来的连接进行加密和解密用的。Legacy paring 中的 LTK 由从设备根据相应的算法自己生成的(LTK 生成过程中会用到 EDIV(分散因子)和 Rand(随机数)),然后通过蓝牙空中包传给主机。

LESC 配对过程中,先通过 Diffie-Hellman 生成一个共享密钥,然后这个共享密钥再对设备 A 和 B 的蓝牙地址和随机数进行加密,从而得到 LTK,LTK 由设备 A 和 B 各自同时生成,因此 LTK 不会出现在 LESC 蓝牙空中包中,大大提高了蓝牙通信的安全性。

°IRK(Identity Resolving Key,蓝牙设备地址解析密钥)

有些蓝牙设备的地址为可解析的随机地址,比如 iPhone 手机,由于他们的地址随着时间会变化,那如何确定这些变化的地址都来自同一个设备呢?

答案就是 IRK,IRK 通过解析变化的地址的规律,从而确定这些地址是否来自同一个设备,换句话说,IRK 可以用来识别蓝牙设备身份,因此其也称为 Identity information。IRK 一般由设备出厂的时候按照一定要求自动生成。

°Identity Address(设备唯一地址)

蓝牙设备地址包括 public,random static, private resolvable,random unresolved 共四类。

如果设备不支持 privacy,那么 identity address 就等于 public 或者 random static 设备地址。

如果设备支持 privacy,即使用 private resolvable 蓝牙设备地址,在这种情况下,虽然其地址每隔一段时间会变化一次,但是 identity address 仍然保持不变,其取值还是等于内在的 public 或者 random static 设备地址。

Identity Address 和 IRK 都可以用来唯一标识一个蓝牙设备。

°IO capabilities(输入输出能力)

是指蓝牙设备的输入输出能力,比如是否有键盘,是否有显示器,是否可以输入 Yes/No 两个确认值。

°Key size(密钥长度)

一般来说,密钥默认长度为 16 字节,为了适应一些低端的蓝牙设备处理能力,你也可以把密钥长度调低,比如变为 10 个字节。

2、Paring 流程及命令

°Paring 包含三个阶段:1、阶段 1:配对特性交换,即交换各自都支持哪些配对特性,比如支不支持 SC,支不支持 MITM,支不支持 OOB,以及它的输入输出能力等。2、阶段 2:密钥生成阶段,legacy paring 和 LESC paring 两者的区别就在这里,因此后续我们会分开阐述 legacy paring 和 SC paring 的阶段 2。

Legacy paring:STK 生成(注:legacy paring 的 LTK 生成跟配对流程无关,如前所述,其是由从机自己生成的)

SC paring:LTK 生成

3、阶段 3:通过蓝牙空中包分发一些秘密信息。Legacy paring 需要分发 LTK,IRK 等,而 SC paring 只需分发 IRK。秘密信息分发之前,必须保证连接已加密。  °Paring 流程如下所示:

2.1 阶段 1:配对特性交换 Paring 流程及命令

°配对特性交换涉及三条 PDU 命令:1、Paring_Request:

2、Paring_Response:

3、Security_Request:

°IO Capability 占一个字节,其定义如下所示:

°AuthReq 也是占用一个字节,其定义如下所示:

2.2 阶段 2:密钥生成

°根据阶段 1 的 IO 输入输出能力以及是否存在 OOB,阶段 2 存在如下几种配对方式(或者说认证方式):

Just works

Numeric comparison(LESC 才有)

Passkey

OOB

对于 legacy paring,如果 A 和 B 都支持 OOB,那么两者就会采用 OOB 方式进行配对,否则根据 IO 能力选择配对方式。对于 SC paring,如果 A 或者 B 有一方支持 OOB,那么两者就会采用 OOB 方式进行配对,否则根据 IO 能力选择配对方式。不同的 IO 能力对应的配对方式如下所示。

粗略来说,有认证的配对方式就具备 MITM 保护功能,从 IO 角度看,有三种配对方式:just works,passkey 和 Numeric Comparison,其中 just works 没有 MITM 保护功能,而 passkey 和 Numeric comparison 具备 MITM 保护功能。换句话说,如果你要求你的设备具备 MITM 保护功能,那么它必须有一定 IO 能力,而不能是“NoInputNoOutput”。至于 OOB 方式有没有 MITM 保护,取决于 OOB 通信的安全性,如果 OOB 通信具备 MITM 保护,那么蓝牙也具备 MITM 保护,否则就不具备。

下面分 legacy paring 和 sc paring 对配对流程进行讲解。

2.2.1 legacy paring

°Legacy paring 整个配对流程是围绕 STK 生成来做的:  设备的认证是通过设备 A 和 B 经由 TK 生成一个确认数,如果这个确认数相同,则认证通过。  如前所述,legacy paring 需要先生成 TK,TK 的生成方式取决于配对方式:

Just works。TK 默认为全 0

Passkey。TK 由 6 位 passkey 扩展而来

OOB。TK 直接由 OOB 数据提供

°然后生成确认数,算法如下所示:

°生成 STK 的算法如下所示:

°以 passkey legacy paring 为例,其第 2 阶段全工作流程如下所示:

Just works 和 OOB 配对流程就不再赘述了,大家自己去看一下蓝牙核心规范的说明。

这里强调一下,配对完成之后,连接就会加密,而且加密的密钥是 STK,而不是 LTK。

对于 legacy paring,如果 A 和 B 都支持 OOB,那么两者就会采用 OOB 方式进行配对,否则根据 IO 能力选择配对方式。对于 SC paring,如果 A 或者 B 有一方支持 OOB,那么两者就会采用 OOB 方式进行配对,否则根据 IO 能力选择配对方式。不同的 IO 能力对应的配对方式如下所示。

2.2.2 LESC paring

°跟 legacy paring 不一样的地方:  LESC paring 是通过 Diffie-Hellman 算法直接生成 LTK,因此它不需要生成 TK 和 STK。为了生成 LTK,双方需要先交换公钥,流程如下所示:

公钥交换后,设备 A 和 B 就开始独自计算各自的 DHKey,按照 D-H 算法,他们俩算出的 DHKey 会是同一个。而 LTK 和 MacKey 就是通过这个 DHKey 加密一系列数据而得到的。

Legacy paring 在整个配对流程中只做一次认证,而 LESC paring 会做两次认证。LESC 第一阶段认证的原理是,设备 A 和 B 各生成一个随机数,然后认证这个随机数对不对。LESC 第二阶段认证过程是:设备 A 和 B 通过 MacKey 各生成一个检查值,对方确认这个值对不对。

以 LESC Numeric comparison 为例,其第一阶段认证流程如下所示:

我们还是以 LESC Numeric comparison 为例,其第二阶段全工作流程如下所示:

一旦 LTK 生成成功,主机端就可以发起加密连接流程,如下所示:

至此,LESC 连接被 LTK 加密了,后面就可以分发秘密信息了。

2.3 阶段 3:秘密信息分发

°一旦连接加密了,主机和从机之间就可以分发一些秘密信息。如果是 legacy paring,如下秘密信息必须分发:

LTK

EDIV

Rand

°同时根据情况,legacy paring 还需分发如下信息:

IRK

Identity adresss

°对于 LESC paring,秘密信息分发是可选,一般有可能分发如下信息:

IRK

Identity adresss

如下为 legacy paring 可能分发的最多秘密信息的一个例子:

2.4 绑定,重连和加密

°如果配对的两个设备生成了 LTK 及其他秘密信息:  如上所述,如果配对的两个设备生成了 LTK 及其他秘密信息,并且把 LTK 及其他秘密信息保存到 Flash 等永久化存储设备中,那么我们就可以说这两个设备绑定成功。换句话说,paring 和 bonding 是两个不同的概念,paring 更强调认证和密钥生成,而 bonding 更强调密钥保存。一旦两个设备 bonding 成功,那么这两个设备断开再次重连的时候,主机就可以发起加密流程,从而使用 paring 生成的 LTK 对后续的连接进行加密。主机发出加密连接流程如下所示:

这里说明一下,加密连接只能由主机发出,而不能由从机发起。不过从机可以发出加密请求,主机收到从机的加密请求后,可以发起加密连接也可以拒绝其请求。如下为主机同意从机的加密请求的工作流程:

2.5 配对命令一览表

°如下为 SM 中用的 PDU 命令列表:  (注:加密连接命令属于 LL 控制命令,所以没有包含在其中)

3. Nordic SDK 配对流程

°如下为 SM 中用的 PDU 命令列表:  那么如何实现这个配对流程呢?也就是说,我该调用哪些 API 去实现配对流程,这些 API 调用的顺序又是如何,具体会产生哪些协议栈事件,该如何处理这些协议栈事件,这就涉及到协议栈的实现。

Nordic 蓝牙协议栈 softdevice 提供详细的工作流程图,以指导用户如何调用 softdevice API 去实现想要的配对流程,详细的配对流程图请参考 infocenter 如下界面:

比如 S132 协议栈,其从机端配对流程图链接为:https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v7.0.1%2Fgroup___b_l_e___g_a_p___p_e_r_i_p_h___s_e_c___m_s_c.html。

以 legacy paring,从机端显示 passkey,主机端输入 passkey 为例,softdevice 的配对流程图如下所示,链接为:

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v7.0.1%2Fgroup___b_l_e___g_a_p___p_e_r_i_p_h___b_o_n_d_i_n_g___p_k___p_e_r_i_p_h___m_s_c.html

上述配对流程图把用到的 API,产生的 softdevice 事件,以及 softdevice 事件如何处理,都一一阐明,大家只要按照这个流程图来做,就可以完成期望的配对。更让人省心的是,Nordic SDK 已经把几种典型的配对场景做成了例子,大家可以直接就拿过来用,连上面的配对流程图都不用看,就可以轻松完成自己的配对应用。

Nordic 提供的配对例子有:ble_app_hids_keyboard,ble_app_hrs,ble_app_gls,ble_app_bps,ble_app_bms,ble_app_cscs,ble_app_hrs_nfc_pairing,experimental_ble_app_hrs_nfc_pairing,ble_app_hids_keyboard_pairing_nfc,ble_app_multirole_lesc 等,基本上囊括了蓝牙各种配对情况。

后面会以 ble_app_hrs 为例来详细讲解如何实现低功耗蓝牙配对

4. 配对例程 ble_app_hrs 解读

°nRF5 SDK 把蓝牙配对做成了一个模块:  peer_manager,也就是说,所有关于 paring 的工作都由 peer manager 自动完成,用户无需去了解 softdevice 底层 API 的使用方法,大家直接参考 nRF5 SDK 里面的例程就可以完成自己的配对应用开发。

nRF5 SDK 提供的配对例子有:ble_app_hids_keyboard,ble_app_hrs,ble_app_gls,ble_app_bps,ble_app_bms,ble_app_cscs,ble_app_hrs_nfc_pairing,experimental_ble_app_hrs_nfc_pairing,ble_app_hids_keyboard_pairing_nfc,ble_app_multirole_lesc 等,基本上囊括了蓝牙各种配对情况,下面将和大家一起来解读 ble_app_hrs 配对相关代码

如果你对 Nordic nRF5 SDK 和 softdevice 不是很熟的话,建议你先看一下这篇文章:手把手教你开发 BLE 数据透传应用程序 ,以建立 Nordic 开发的一些基础知识,然后再往下看。  跟没有 paring 的 ble 应用代码相比,有 paring 的 ble 应用只多了一个初始化函数:peer_manager_init(),peer_manager_init 实现代码如下所示:

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

至此,一个 just works 的蓝牙配对例子就算完成了,是不是有点懵?感觉太简单了以至于有点接受不了。没关系,下面我们在这个例子上加一些额外的功能,以加深大家对它的理解。

5. 改变 ble_app_hrs 配对方式

°把 ble_app_hrs 配对方式改成 LESC with numeric comparison:  原始 ble_app_hrs 为 just work 方式的 LESC 配对,我们现在把它改成最高安全级别的 numeric comparison LESC。我们的开发板没有显示器,因此我们将通过日志的方式把数字比较值输出,同时把 button3 的按下作为 yes 确认,button4 的按下作为 reject 确认。

何实现 numeric comparison?前面我也提过,如果 SDK 有现成的例子,直接参考例子来;如果 SDK 没有现成的例子,那么就参考 softdevice 工作时序图。关于 LESC numeric comparison,从机端的工作流程如下所示:

https://infocenter.nordicsemi.com/index.jsp?

topic=%2Fcom.nordic.infocenter.s132.api.v7.0.1%2Fgroup___b_l_e___g_a_p___p_e_r_i_p_h___l_e_s_c___b_o_n_d_i_n_g___n_c___m_s_c.html

这里要强调一下,时序图会把有可能需要用到事件和 API 都列出来,但不意味着列出来的事件和 API 都需要你那哪些事件和 API 需要用户自己处理呢?一个原则:全文搜索一下,只要 peer manager 已经调用过的 API,你就不用处理;而流程图中剩下的 API 就需要你自己去处理了。

比如上面这个例子,sd_ble_gap_sec_params_reply 已经被 peer manager 模块处理了,所以你不用处理;而 BLE_GAP_EVT_PASSKEY_DISPLAY 和 sd_ble_gap_auth_key_reply 只在 passkey 和 numeric comparison 配对方式中才会出现,peer manager 没有对其进行处理,因此需要用户自己处理。为此,我们在 ble_evt_handler 中加上分支:BLE_GAP_EVT_PASSKEY_DISPLAY,并按照流程图的要求加上相应的处理,代码如下所示:

上面只是显示了 passkey,如前所述,如果 button3 按下我们回复 BLE_GAP_AUTH_KEY_TYPE_PASSKEY;如果 button4 按下我们回复 BLE_GAP_AUTH_KEY_TYPE_NONE。相关代码如下所示:

如前所述,配对方式是由 IO 输入输出能力确定的,而且 numeric comparison 是具备 MITM 能力的,为此我们还需要修改如下两个地方:

苹果手机是不能手动发起配对请求的,为了让苹果手机自动发起配对请求,我们将如下 characteristic 的安全级别提高:(注:除了这种方法,我们也可以通过从机主动发起安全请求来达到同样的目的)。

我这里以 PCA10040/Keil5 工程为例来编译,请编译工程:

nRF5SDK160098a08e2examplesle_peripheralle_app_hrspca10040s132arm5_no_packs。

将编译好的代码下载到开发板中,测试的时候,我们先连接开发板,然后使能 CCCD,此时不管 Android 手机还是苹果手机,都会跳出配对对话框,同时显示出配对码,如下:

开发板也把配对码打印出来了,如果两者一致,按下 button3,整个配对流程顺利完成,开发板会打印如下信息:

上述代码已上传到百度云盘,大家可以去百度云盘下载:

代码链接

链接:https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog

密码:y8fb

ble_app_hrs_nc.rar,然后解压缩到 SDK 根目录 examplesble_peripheral,打开 Keil5 工程:

SDK 根目录 examplesble_peripheral ble_app_hrs_ncpca10040s132arm5_no_packs,就可以直接编译和运行。

6. 关于配对的一些小贴士

°苹果手机的一点不同:  安卓手机允许用户手动发起 paring 请求,而苹果手机则没有这个功能。因此,即使你的 characteristic 没有使能安全级别,安卓手机还是可以跟你的设备完成配对的,而苹果手机则不支持这个功能,苹果手机要不要跟设备进行配对,不能由人来控制的,只能由苹果 iOS 来控制。  欲触发苹果 iOS 发起配对请求,有两种方法:

一是将某个 characteristic 加上安全认证权限,这样 iOS 在服务发现过程中就会自动发起配对请求,以满足 characteristic 的安全认证级别;

二是从机端主动发起安全请求,iOS 收到从机的安全请求后,会等待用户的授权确认从而发起配对请求。这两种方法在 ble_app_gls 中都有体现,大家可以参考相关代码。

°重连加密等级:  绑定成功后,如果发生重连,那么主机应该自动发起加密连接请求,以对连接进行加密。一般来说,在连接没有成功加密前,主从机不要做敏感数据的交互,否则 softdevice API 会报 NRF_ERROR_FORBIDDEN。对于有 MITM 保护的加密连接,在收到 PM_EVT_CONN_SEC_SUCCEEDED 这个事件后,设备应该去检测连接的安全等级是否符合要求,具体可参考 ble_app_gls 例子的做法。  °Service changed(服务改变):  设备跟手机绑定成功后,手机再次重连这个设备时,就会自动跳过 service discovery 过程,换句话说,配对的时候手机会把设备所有服务和 characteristic 的 handle 保存下来,二次重连的时候,直接用以前保存的 handle 值去操作设备。

但是,如果设备的服务改变了,此时手机再用之前的 handle 去操作设备,就会出问题。为了解决这个问题,在 GATT 主服务里面引入了 service changed characteristic,如下所示:

有了这个 characteristic,当设备的服务发生改变时,设备就可以通过这个 characteristic 发送一个 indicate PDU 给到手机,从而手机知道设备的服务已发生了改变,此时手机会重新发起 service discovery 流程,以重新获得 service 和 characteristic 最新的 handle 列表。欲添加 service changed characteristic,你只需在 sdk_config.h 文件中打开如下两个宏:

然后当服务发生改变时,调用 pm_local_database_has_changed(),协议栈就会自动发起 service changed indicate PDU 给手机,从而引起手机重走服务发现过程。

°删除主机端绑定信息: 如果手机端删除了绑定信息,为了安全起见,设备端也需要跟着一起删除绑定信息,否则手机无法再次跟设备进行配对,这个是最理想的情况,但是我们有的设备没有任何输入接口,无法手动删除绑定信息,这个时候能不能有一种办法可以让手机跟设备进行二次配对呢?

为此,Nordic 提供了一种 workaround,在蓝牙事件回调函数里面,加上如下代码即可:

if (p_evt->evt_id == PM_EVT_CONN_SEC_CONFIG_REQ)

{

pm_conn_sec_config_t cfg;

cfg.allow_repairing = true;

pm_conn_sec_config_reply(p_evt->conn_handle, &cfg);

}

这样,即使用户把手机端 paring 信息删掉,设备端 paring 信息没有删掉,手机还是可以跟设备进行二次配对的。

°删除从机端绑定信息:  跟上面相反,如果设备端 bonding 信息被删除了,而手机端 bonding 信息没有被删除,这种情况下如何实现二次配对?

最安全的方式,让用户主动删除手机端绑定信息,但是很多开发者希望,用户体验好一点,也就是说,碰到这种情况希望手机能自动删除绑定信息,这个能不能实现跟手机有很大关系,首先我们确保协议栈返回 LL_REJECT_IND or LL_REJECT_EXT_IND,错误码为“PIN or key missing”,一般而言,手机收到这个 PDU 后,都会自动删除 bonding 信息。

如果上述方法行不通的话,那么发送完 LL_REJECT_IND 后再调用断开函数(sd_ble_gap_disconnect),同时将断开原因设为 BLE_HCI_AUTHENTICATION_FAILURE 即可。

°同时绑定多个设备:  Nordic SDK 是支持一个设备同时跟多个主机绑定,只要设备存储空间足够大,那么可以绑定的设备数就不设限。nRF5 SDK 中 bonding 信息也是通过 fds 来存储的,也就是说绑定信息和用户 Flash 数据共享同一块空间,如果需要绑定多个设备,那么 FDS_VIRTUAL_PAGES 这个宏的值必须进行修改,以保证分配的 Flash 空间可以同时容纳 bonding 信息和用户 Flash 数据。

一般来说,如果需要绑定多个设备,请设置一个最大绑定数,比如 8 个,这样,一旦检测到绑定数达到 8 了,就可以把以前老的 bonding 设备删除,从而节省存储空间。那如何知道哪个设备是老设备哪个设备是新设备?这个是通过 peer rank 来实现的,大家只要使能 PM_PEER_RANKS_ENABLED 这个宏,就可以自动实现排序。

°循环绑定测试:  很多开发者喜欢做循环绑定测试,即同一部手机不断跟同一个设备进行配对,然后删除配对信息,然后再进行配对,他们测试下来发现:

达到一定次数后,设备就工作不正常了,这个是由于当 bonding 信息不断累积而不进行删除的话,那么分配给 fds 的 Flash 空间就会耗尽,从而导致异常出现(最新的 SDK 会在 Flash 存储空间耗尽时,自动删除最老设备的绑定信息,但即使这样,对用户 Flash 数据的操作影响还是很大)。

解决这个问题的方法就是设定一个最大 bonding 数,达到这个数目后,删除老 bonding 信息,从而达到循环利用 Flash 空间的目的。当然如果你的 fds 只是用来存储 bonding 信息而不做其他用户数据操作的话,那么就没有必要加上这个功能了。

°白名单与绑定:  虽然白名单和绑定二者没有任何联系,但是我们一般都把两者结合起来一起使用,以达到我们的使用期望。当两个设备绑定成功后,我们就可以将对方的 mac 地址或者 IRK 放入白名单中,同时开启白名单广播,这样设备只跟白名单中的主机进行连接,白名单以外的设备在 controller 层面就被过滤掉了,从而提高私密性以及连接效率。

这种情况下,哪怕是合法的设备,如果之前没有跟设备绑定,那么它也无法跟设备建立连接。换句话说,如果你想把新设备加入到白名单中,那么首先需要禁止白名单广播而采用普通广播,然后跟新设备进行配对,成功后再把新设备身份信息加入到白名单中。白名单与绑定的例子具体可参考:ble_app_hids_keyboard。

°Authenticated payload timeout:  大家都知道蓝牙连接有一个 supervision timeout 时间,也就是说,当建立连接的两个设备,任何一方在 supervision timeout(比如 4s)时间内,没有给对方发送任何蓝牙空口包,此时认为连接已断开,并触发 supervision timeout 事件。

当设备双方建立加密连接后,不仅有上述的 supervision timeout,还有一个 authenticated payload timeout,authenticated payload timeout 默认为 30s,它的意思是,两个设备加密后,30s 内必须有一个有数据的空口包交互,而不能一直发空包,否则认为 authenticated payload timeout。

Authenticated payload timeout 是协议栈自动管理的,对软件开发来说是透明的,每 30s 时间到,如果期间没有任何有效数据包交互(一直在发空包),协议栈会自动发送一个 ping request 给对方,以避免 authenticated payload timeout 的出现(注:这里的协议栈既可以是设备的协议栈,也可以是手机的协议栈)。

有时候不想等到 30s 超时到了再发送 ping request,大家可以在 connected 事件中,调用如下 API 以提前发出 ping request。

当然,如果你能保证每 30s 时间内,手机和设备之间肯定会有有效数据包交互,或者手机端能及时准确地发出 ping request,那么上述过程就完全没有必要了。

低功耗蓝牙密钥NFC