一、前言
本篇会结合蓝牙协议文件,将本设备的irk(身份可解析秘钥)、MAC地中中的prand(mac地址中的高3位)输入python代码中来生成本地hash(哈希值),从而确定当前的设备地址是否合法。
二、阅读说明
1、泰凌微芯片学习者,前期使用过该芯片。
2、能够知道怎么进行创建工程,下载代码。
3、有一块开发板,板上的芯片可以是8251,8253或者8258。
4、需使用蓝牙抓包工具52840 Sniffer和协议分析软件Wireshark
三、正文
1、使用的SDK使用的sdk和demo为该篇文章描述的“手把手教你:将广播的公共地址更改为可解析的私有地址”,微信公众号文章链接为:如何使用TLSR8258芯片进行蓝牙广播
2、可解析的私有地址
-
- prand:24bits,广播Mac地址的高3字节,其中最高2bits为01,固定不变,其余的22bits为随机值hash:24bits,广播Mac地址的低3字节,通过AES-128 ECB加密计算得到的,计算的时候,需要带入本地的irk(身份可解析秘钥),和prand值即可,公式如下:
3、如何确定设备是否合法
将上述的描述简单解释一下,在当前的demo当中,我们能通过打印得到当前设备的irk(身份解析秘钥),并且可以通过扫描得到当前设备的mac地址,那么我们就可以利用AES-128 ECB来计算出一个临时的hash值,之后对比计算出来的临时hash值与广播地址的低3字节进行比对,如果值是一样,那么就是合法,如果不一样那么广播地址就是非法的,不属于可解析的私有地址。
4、运行demo,打印出当前设备的irk
97 89 bf 36 4c e9 3d 09 45 5e 8b 09 fd 35 73 8b
注意参与计算时,该16bytes需要反一下。
5、用nRf Connect软件搜索“feature”的广播包
该设备的广播mac地址为:
57:70:58:11:09:C9
该设备的prand值为:、
57:70:58
该设备的hash值为:
11:09:C9
6、编写python文件,将irk和prand输入,得到临时的hash
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modesfrom cryptography.hazmat.backends import default_backenddef ble_ah(irk: bytes, prand: bytes) -> bytes:"""BLE 可解析私有地址 RPA 哈希函数 ah(k, r):param irk: 16字节 IRK 配对解析密钥:param prand: 3字节 从RPA前3字节提取的随机值:return: 3字节 localHash,用于和RPA后3字节hash比对"""# 构造128bit明文 r' = 104bit零填充 + 24bit prandr_prime = bytes(13) + prand#print(f"r_prime hex: {r_prime.hex()}")# AES-128 ECB 加密(蓝牙规范定义的安全函数e)backend = default_backend()cipher = Cipher(algorithms.AES(irk), modes.ECB(), backend=backend)encryptor = cipher.encryptor()cipher_text = encryptor.update(r_prime) + encryptor.finalize()# mod 2^24:取密文最低24bit(最后3字节)return cipher_text[-3:]if __name__ == "__main__":# ---------------------- 可修改输入区 ----------------------#input_irk_hex = "9789bf364ce93d09455e8b09fd35738b" # 你的IRKinput_irk_hex = "8b7335fd098b5e45093de94c36bf8997" # 你的IRKinput_prand_hex = "577058" # 你的prand# ---------------------------------------------------------# 十六进制字符串转字节数组irk = bytes.fromhex(input_irk_hex)prand = bytes.fromhex(input_prand_hex)# 参数合法性校验if len(irk) != 16:raise ValueError("IRK 长度必须是16字节(32位十六进制字符)")if len(prand) != 3:raise ValueError("prand 长度必须是3字节(6位十六进制字符)")# 计算本地哈希local_hash = ble_ah(irk, prand)# 格式化打印结果print("===== BLE ah() 哈希计算结果 =====")print(f"IRK : {input_irk_hex}")print(f"prand : {input_prand_hex}")print(f"localHash : {local_hash.hex()}")
注意:python需要安装库文件
pip install cryptography
7、运行python得到如下结果
===== BLE ah() 哈希计算结果 =====IRK : 8b7335fd098b5e45093de94c36bf8997prand : 577058localHash : 1109c9
其中localHash是计算出的临时的hash值,该值和5小节中的hash值一样,说明该设备为合法设备。
五、结尾
本篇结合蓝牙协议文件和python代码,分析了如何判断可解析的私有地址的合法性,下一篇将依然是蓝牙加密方面的文章,不是通过python来进行加密,而是通过泰凌的库来进行加密。
另外我开了一个手写广播设备的合集,该合集的内容为不依赖商业的蓝牙协议栈,里面的内容主要是结合蓝牙协议文件,分析一个完整的广播数据帧结构,然后通过编写底层代码(不依赖泰凌微蓝牙协议栈),来实现自己的广播设备,之后会结合蓝牙广播要求对代码进行优化,做到可以三通道发送。
253