Fast Pair服务
fast pair 服务的UUID 是0xFE2C,然后它又包含多个特征值,下面一一分析:
Model ID
UUID是0x1233,设备在谷歌云注册的时候会分配一个24 bit的ID。
Key-based Pairing
UUID是0x1234,这个是用来做DH密钥交互,最终同步共享密钥的,seeker发送第一个key based pairing request会带上加密的16 byte data和512bit的手机public key。provider会回复一个key based pairing response给seeker,这个response会附带上provider的BR地址,以供seeker发起pair。
这里面涉及一个预共享密钥的概念,预共享密钥就是用来生成AES Key的临时密钥,假设为K,这个密钥的值在以下两种情况下是不同的:
- 如果provider是第一次配对,没有account key的情况下,那么seeker需要通过DH算法生成防欺骗的private/public key对,然后双方交换公钥,通过ECC secp256r1算出来。
- 如果provider有account key,那么这个预共享密钥就是account keys其中的一个。
先来看看key based pairing request的数据格式:
加密后的格式:
provider解密后的格式:
上图是message type 为0x00的数据格式,下面还有一个message type为0x10的action request的数据格式用来发送addtional data:
再看看key based pairing response的数据格式:
加密后的格式:
解密后的格式:
Passkey
UUID是0x1235,在BR蓝牙基于Numeric配对后,对6-digit做数字校验。
先看下加密后的数据格式:
再看下解密后的数据格式:
Account Key
UUID是0x1236,这个是通过K用SHA256做哈希后,取前128bit ,用来做AES加解密的128bit key,一个provider最少要能够保存5个。这个数据格式就是16字节的数字串,简单。
Additional Data
UUID是0x1237,要操作这个特征值,seeker和provider必须通过key based pairing流程获取了共享密钥,这个特征值的数据会通过ASE-CTR技术加密方式进行,这种方式安全性更高。HMAC-SHA256会用来做数据校验。
看一下数据格式:
当seeker给provider发一个通知,要求provider提供personalized name的时候,会通过key based pairing request的第一个字节的BIT2置上1,然后provider就会发送如上图格式的数据给seeker,上图的那些数据是通过如下方式生成的:
- 生成8字节一次性随机数Nonce,如上图8-15字节。
- 采用ASE-CTR加密方式,每16个字节成一个块,采用如下公式进行:
encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
- 串联(encryptedBlock[0], encryptedBlock[1],…)组成加密数据
- 用如下公式生成HMAC-SHA256 :
sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))
注意这里的K是16字节密钥和48个0组成的数组,opad是64字节的数组,成员值全部是0x5C;ipad也是64字节数组,成员值全部是0x36。然后取前8个字节的哈希值作为HMAC-SHA256。
如果provider是收到了一个写personalized name请求,那么他需要做相反的工作:
- 首先需要校验HMAC-SHA256的完整性。
- 用如下公式解密数据:
clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))