FMDN
FMDN也就是Find My Device Network,它定义了一种端对端的加密方式来定位跟踪BLE beacon设备,说白了就是一种通过BLE来定位跟踪设备位置的技术,苹果也搞了一个类似的技术叫Find My。要实现这个技术,Provider需要满足FMDN的规范和打开定位功能。
GATT 特征值
Provider会作为BLE beacon发专门为FMDN定制的广播,所以我们需要特意定义一个额外的GATT特征值“beacon action”,UUID为0x1238,定义如下:
Fast Pair Service characteristic | Encrypted | Permissions | UUID |
---|---|---|---|
Beacon actions | No | Read, write and notify | FE2C1238-8366-4814-8EB0-01DE32100BEA |
认证
当Seeker需要写Provider的beacon action特征值的时候,我们会通过挑战-响应机制来认证。首先Seeker会去读取beacon action特征值,然后Provider会返回9个字节,一个字节协议版本和8字节的一次性随机数,然后Seeker会利用这个随机数和版本号,account key等参数通过SHA-256产生的结果,取前8个字节生成一个一次性的认证码,Seeker后面发起的写操作,都会带上这个8字节的认证码,Provider需要进行认证,如果认证通过,那么会返回Seeker想要的结果,否则返回认证失败。在操作beacon action特征值时,我们会涉及到以下6个key:
- Account key:这个就是我们GFPS定义的账户key。
- Owner account key:就是Provider里面存在多个account key的时候,我们需要选择其中的一个account key,在操作beacon action特征值时加密数据。这个account key一般都是第一次配对或者最近使用的account key。
- Ephemeral identity key (EIK):这是个临时密钥,用来加密位置信息的,是Seeker在FMDN配置过程中设置的一个32字节随机数,这个密钥不会保存在云端。
- Recovery key:这个是保存在云端,万一Seeker在某些情况把EIK给弄丢了,可以通过Seeker发送Recovery key给Provider,Provider把EIK发送给Seeker。它的计算方法是:SHA256(ephemeral identity key || 0x01)的结果取前8个字节。
- Ring key:这个是让Provider响铃的key,存储在云端。他的计算方法是:取SHA256(ephemeral identity key || 0x02)结果的前8个字节。
- Unwanted tracking protection key:这个key是用来激活unwanted tracking protection mode的,保存在云端。它的计算方法是:取SHA256(ephemeral identity key || 0x03)结果的前8个字节。
beacon action写操作
Seeker写beacon action特征值,我们总共定义了九个命令,根据Data ID来区分,如下:
- Read beacon parameters:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x0 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
- Read provisioning state:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x1 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
- Set ephemeral identity key:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x2 |
1 | uint8 | Data length | 16或者40 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
10 - 41 | byte array | Additional data | 32 字节的ephemeral identity key, 利用account key AES-ECB-128方式加密.如果Provider已经存在 ephemeral identity key, 那么就发送 SHA256(current ephemeral identity key || the last nonce read from the characteristic) 的前8个字节。 |
- Clear ephemeral identity key:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x3 |
1 | uint8 | Data length | 16 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
10 - 17 | byte array | Additional data | 取 SHA256(current ephemeral identity key || the last nonce read from the characteristic) 结果的前8个字节。 |
- Recovery ephemeral identity key with user consent:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x4 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
- Ring:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x5 |
1 | uint8 | Data length | 12 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
10 | uint8 | Ring operation | A bitmask having the following values: Bit 1 (0x01): Ring right Bit 2 (0x02): Ring left Bit 3 (0x04): Ring case 0xFF: Ring all components 0x00: Stop ringing |
11 - 12 | uint16 | Timeout | The timeout in deciseconds. Must not be zero and must not be greater than the equivalent of 10 minutes. The Provider uses this value to determine how long it should ring before silencing itself. The timeout overrides the one already in effect if any component of the device is already ringing.If ring operation is set to 0x00, the timeout is ignored. |
13 | uint8 | Volume | 0x00: Default 0x01: Low 0x02: Medium 0x03: High The exact meaning of these values is implementation dependent. |
- Read ringing state:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x6 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
- Activate unwanted tracking protection mode:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x7 |
1 | uint8 | Data length | 8或者9 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
10 | uint8 | Control Flags | 这是一个可选的字节,0x01: Skip ringing authentication. When set, ringing requests aren’t authenticated while in unwanted tracking protection mode. |
- Deactivate unwanted tracking protection mode:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x8 |
1 | uint8 | Data length | 16 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data) |
10 - 17 | byte array | Additional data | 取 SHA256(current ephemeral identity key || the last nonce read from the characteristic) 结果的前8个字节。 |