一直对配对绑定充满好奇,于是我抓了一次完整的包,对着协议解析了一次。不算深入理解,只是知道大概的流程是怎么回事。
/*********************************************************************************/
SM 在BLE协议栈的位置:
介绍:
安全管理。每个设备生成并分配其生成的密钥。设备之间进行相互配对,连接一段加密,设备必须分配用于加密,保障隐私并对消息进行验证的密钥。当设备把配对的密钥在flash保存下来,设备就处于绑定状态。之后两个设备第二次重连时安全启动会更快,不需要像第一次一样再启动整个配对过程。
配对:两端蓝牙设备加密特性的交换,并创建临时密钥。之后连接用临时密钥加密,提高了蓝牙交互的安全性。
绑定:在配对之后交换和保存长期密钥,用于之后的连接。如果一个手环已经和手机绑定,他们可以不必再配对就可以加密重连,手机仅仅需要请手环“开启加密”,双方就可以使用已经存储的加密密钥通讯。
绑定对于配对来说是个可选配置,有绑定则下次重连不需要再配对,没有绑定,则每次重连都需要配对。
配对流程:
配对有三个阶段:
1.配对信息交换(主要就是两边设备的I/O能力,设置绑定标准,链路是否需要MITM保护,如果设置设置绑定,需要分配那些密钥信息等等);
2.链路认证(比如手机输入的配对密码,动态密码,静态密码之类的,密码认证的过程)
3.密钥分配(绑定可选)
第一阶段:配对信息交换:主要是配对请求和配对响应数据包(当配对开始时,1个设备要发起Pairing Feature Exchange,响应设备如果不支持配对或者配对无法执行,响应设备应响应配对失败的消息,表示不支持配对,否则响应支持配对的消息)
配对请求数据包格式:
抓包数据分析:(手机->设备)(附录1:WireShark记录)
Code:
IO Capability:(描述了设备的输入和输出能力)
0x00:设备具有只有显示功能
0x01:设备有显示功能,并且至少有两个按键可以表达YES or NO
0x02:设备只有一个数字键盘(0-9)和一个确认按键。
0x03:设备没有键盘,没有显示屏
0x04:设备有显示功能,并且有数字键盘
0x05-0xff:RFU
OOB data flag:(采用外部通讯方法交换一些配对过程中使用的信息,OOB可以是任何一种能够传输响应信息的其他无线通信,如NFC或二维码)
0x00:不存在OOB
0x01:来自远程设备的OOB身份验证数据
0x02-0xff:RFU
AuthReq:(授权请求,表示STK ,LTK和 GAP绑定信息请求的安全属性)
Bonding_Flags:绑定标志位 (0b00 不绑定,0b01 绑定)
MITM: (中间人保护标志位)如果设备正在请求MITM保护,则设置为1,否则设置为0。(参考:ble笔记_MITM攻击)
SC: 1表示请求低功耗安全连接。两台设备都支持配对,则使用安全连接,否则采用传统配对。
Keypress:仅当密码输入协议中使用,其他协议忽略。当双方均将该字段设为1,则应使用SMP PairingKeypress Notification PDUs(code 0x0E).发送按键通知。
CT2:1 传输时被设置为1 .支持h7功能
Maximum Encryption Key Size (1 octet)
定义了设备可以的支持的最大加密密钥长度(7-16字节)
Initiator Key Distribution / Generation (1 octet)
发起者密钥分配/生成,设置发起配对者的密钥分配机制
Responder Key Distribution / Generation (1 octet)
响应者密钥分配/生成,设置响应配对者的密钥分配机制
密钥分配主要是5种密钥机制
临时密钥(TK)
短期密钥(STK)
长期密钥(LTK)(包含EDIV 和Rand):用于记录加密后的链接
身份解析密钥(IRK) :用于解析随机地址
连接签名解析密钥(CSPK) :用于签名和验证签名
注:EDIV,辅助密钥,用于识别LTK,每次刷新LTK都会重新生成。Rand,用于识别LTK,每次刷新LTK都会重新生成
EncKey:
传统配对中,1表示设备应使用Encryption Information(code:0x06)分发LTK。EDIV和Rand 使用Master Identification(code :0x07)来生成。
在LE安全连接中,当SMP在LE传输上运行时,将忽略EncKey字段。EDIV和Rand应设置为零,不得进行分配。,
IdKey:
设置为1,表示设备应使用Identity Information(0x08)分发IRK,然后使用其公共设备或使用身份地址信息分发静态随机地址。
SignKey
设置为1,表示设备应使用Signing Information(0x0A)分发CSRK。
LinkKey:
当SMP在LE传输上运行时,LinkKey字段被设置为1,以指示设备希望从LTK派生出LinkKey。当Initiator Key Distribution / Generation 和 Responder Key Distribution / Generation 字段中的两个设备都将LinkKey设置为1时,应使用从LTK计算BR/EDR链接密钥的程序。不支持LE安全连接的设备应将此位设置为零,并在接收时忽略它。当SMP在BR/EDR传输上运行时,将保留LinkKey字段以供将来使用。
范例:解析抓包数据:
手机->设备:Pairing Request : 0x01 0x04 0x00 0x2d 0x10 0xf 0xf
设备->手机:Pairing Response :0x02 0x03 0x00 0x01 0x10 0x7 0x7
分析过程:
IO Capability
手机:0x04:设备有显示功能,并且有数字键盘 设备:0x03 设备有显示功能,并且有数字键盘
参考以下配对算法:得出采用 【正常连接】方式配对
OOB data flag:
手机:0x00 ,设备:0x00 没有OOB
AuthReq:
手机0x2d:绑定,使用MITM,加密连接配对, 设备:0x01 绑定,不使用MITM,传统连接配对。
Maximum Encryption Key Size:
手机:0x10 16字节 设备:0x10 16字节
Initiator Key Distribution / Generation :
手机:0xf, 设备:0x07 (协商结果:LTK不派生linkkey)
Responder Key Distribution / Generation (1 octet)
手机:0xf, 设备:0x07 (协商结果:LTK不派生linkkey)
-------------------以上配对第一阶段结束,双方设备的特性进行交换对比,为第二阶段准备----------
传统配对和低功耗安全连接是两条分支,它们的密钥生成方式:
直接连接(Just Works):方法无需输入密码,两端设备仍然执行加密动作,但是TK(初始密码)设为0。这种方法产生的链路是未认证的(Unauthenticated)。在实际使用中,Just Works在配对时候手机屏幕会有弹窗,用户仅需要点一下确认即可。
万能钥匙(Passkey Entry):以一个6字节密码为初始密码,执行加密动作。由于初始密码为随机生成,因而能够保证后续加密行为的安全性。这种方法产生的链路是认证的(Authenticated)。在实际使用中,需要设备具有输出能力用以显示密码,在手机端输入密码,或者反过来设备端有一个输入键盘,手机端提供密码
·带外数据(Out-of-Band,简称OOB):OOB是指利用第三方途径,比如NFC或者WIFI,将Passkey传输给对方。只要这个第三方途径足够安全,就能够保证Passkey的安全,从而避免攻击设备截获Passkey。这个方案受限于第三方途径的匮乏以及操作的复杂性,到目前没有看见有人使用。
低功耗安全连接,除了以上三种方法以外,还增添了一种新方法:
·数值比较(Numeric Comparison):两个设备自行协商生成 6 个数字,并显示出来(要求两个设备具有显示能力),用户比较后进行确认(一致,或者不一致,要求设备有简单的yes or no的确认能力)。
由第一阶段:我们可以看出抓包设备走的是传统配对,密钥生成方式为 Just Works
主机confirm 计算: Just Works 模式下,TK(临时密钥:0x00)
Mconfirm = c1(TK, Mrand, Pairing Request command,Pairing Response command, initiating device addresstype, initiating device address, responding device addresstype, responding device address)
从机confirm计算: Just Works 模式下,TK(临时密钥:0x00)
Sconfirm = c1(TK, Srand, Pairing Request command,Pairing Response command, initiating device addresstype, initiating device address, responding device address type, responding device address)
抓包数据分析:
PairingConfirm (Mconfirm):
Code:0x03
Confirm Value: 4bcc93626ff3804bb0510707b01a42cf
PairingConfirm (Sconfirm):
Code:0x03
Confirm Value: 393d84decb7844a99e055d4c8a23bc42
PairingRandom (Mrand):
Code:0x04
Random Value: 935acf3532d748034e5a3c93bed7d773
PairingRandom (Srand):
Code:0x04
Random Value: 7db47c81b175e6691b5e192b4e1f8313
双方验证通过后,使用交换的rand confirm 使用下面公式生成STK:
STK=s1(TK,Srand,Mrand);
这两个交互主要是为了生成STK的,就是我们平时配对输入密码确认的过程。只不过这个例子中密码默认为0,不用手输入。
-以上配对第2阶段结束,双方设备的进行了密码认证,生成了STK,有了STK,就可以加密链路。加密链路并非神秘,它就是向控制器发送一个加密链路的HCI命令(Set_Connection_Encryption,0x0013),具体实施由控制器底层去处理。加密之后的链路,通信数据都要经过密钥进行加密解密。
此时因为第一阶段明确次流程启用了绑定环节,所以到了第三阶段。密钥的分发由第一阶段协商决定。
抓包数据验证:
从机->主机:
Encryption Information (Long Term Key)
code:0x06
Long Term Key: 29b55ea9939dc891c75efc523147663b
Master Identification (EDIV, Rand)
code:0x07
Encrypted Diversifier (EDIV): 0xb951
Random Value: 9f19d40d090207cf
Identity Information (Identity Resolving Key)
code:0x08
Identity Resolving Key: 1a324f264df382e7b7dbeccfeb9c2091
Identity Address Information :
Opcode: Identity Address Information (0x09)
Address Type: Public (0x00)
BD_ADDR: Private_11:11:11 (11:11:11:11:11:11)
Signing Information (Signature Key)
Opcode: Signing Information (0x0a)
Signature Key: 377f364c6b40a03456e38bd7c0cbbe98
主机->从机:
Encryption Information (Long Term Key)
Opcode: Encryption Information (0x06)
Long Term Key: 2010989f5a0d298300b7484fb7f51280
Master Identification (EDIV, Rand)
Opcode: Master Identification (0x07)
Encrypted Diversifier (EDIV): 0x7d2e
Random Value: 86a9530129a79245
Identity Information (Identity Resolving Key)
Opcode: Identity Information (0x08)
Identity Resolving Key: 365a4a55239461f7750ba550b98742cc
Identity Address Information :
Opcode: Identity Address Information (0x09)
Address Type: Public (0x00)
BD_ADDR: SamsungE_59:14:81 (20:32:6c:59:14:81)
Signing Information (Signature Key)
Opcode: Signing Information (0x0a)
Signature Key: e56c3f6e70cd980d0267aa98fd554793
---------------------------------------------第三阶段绑定结束----------------------------------------------
接下来测试重连:
绑定之后,重连主机会发起 加密流程(已经存在LTK):
协议资料:
LL_ENC_REQ:
LL_ENC_RSP:
2.4.2.6 LL_START_ENC_REQ
The LL_START_ENC_REQ PDU does not have a CtrData field.
2.4.2.7 LL_START_ENC_RSP
The LL_START_ENC_RSP PDU does not have a CtrData field.
抓包解析:
LL_ENC_REQ:
Control Opcode: LL_ENC_REQ (0x03)
Random Number: 14917894528598022559 (0xcf0702090dd4199f)
Encrypted Diversifier: 47441 (0xb951)
注:Random Number,Encrypted Diversifier是绑定时生成的,用于标识某一个具体的LTK(0x29b55ea9939dc891c75efc523147663b)
Master Session Key Diversifier: 4901802022275727269 (0x4406b2f7e9093fa5)
注:这是一个64bits的随机数(SKDm) ,用于和SKDs一起生成本次加密的session_key
Master Session Initialization Vector: 3857481247 (0xe5ec7e1f)
注:32bits 的随机数(IVm),和 IVs 一起组成 64bits 的 IV,后面 Encryption Engine 会使用。
LL_ENC_RSP:
Control Opcode: LL_ENC_RSP (0x04)
Slave Session Key Diversifier: 59462768229064293 (0x00d3411299a79e65)
注:这是一个64bits的随机数(SKDs) ,用于和SKDm一起生成本次加密的session_key
Slave Session Initialization Vector: 1066802415 (0x000000003f961cef)
注:32bits 的随机数(IVs),和 IVm 一起组成 64bits 的 IV,后面 Encryption Engine 会使用。
LL_START_ENC_REQ:
Control Opcode: LL_START_ENC_REQ (0x05)
LL_START_ENC_RSP:
Control Opcode: LL_START_ENC_RSP (0x06)
参考文档:https://blog.csdn.net/liwei16611/article/details/85101115?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164016309016780271558951%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164016309016780271558951&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-85101115.pc_search_insert_es_download&utm_term=ble+%E5%8A%A0%E5%AF%86%E8%BF%9E%E6%8E%A5%E8%BF%87%E7%A8%8B&spm=1018.2226.3001.4187
小结:以上使用了一次Just Works 传统配对绑定的方式,粗略解析了配对绑定的过程。配对绑定最关键的一步在于第一阶段,这个阶段要弄懂所以参数的意义。后续流程都是按参数选择下一阶段的操作流程。
配对的另一条支路:低功耗安全连接。这块还没时间整理,也挺好奇