特性

快速配对服务

快速配对提供商应提供以下 GATT 服务。

服务 UUID
快速配对服务 0xFE2C

此服务应具有以下特征。

快速配对服务特征 已加密 权限 UUID
模型 ID 读取 FE2C1233-8366-4814-8EB0-01DE32100BEA
基于密钥的配对 撰写和通知 FE2C1234-8366-4814-8EB0-01DE32100BEA
通行密钥 撰写和通知 FE2C1235-8366-4814-8EB0-01DE32100BEA
账号密钥 写入 FE2C1236-8366-4814-8EB0-01DE32100BEA

设备信息服务

快速配对提供程序还应支持设备信息服务。

服务 UUID
设备信息服务 0x180A

快速配对搜寻器使用以下特性。

名称 已加密 权限 UUID
固件修订版本 读取 0x2A26

特征:模型 ID

此特征允许 Seeker 根据需要读取模型 ID, 当设备以可检测到模式进行通告时触发。它应该始终返回 以下数据:

八位字节 数据类型 说明
0 - 2 人 uint24 模型 ID 不定

特性:基于密钥的配对

此特性控制基于密钥的配对过程。在此过程中 通过验证寻找者和 提供方均拥有预共享密钥。键的区别在于 :

  • 案例 1:预共享密钥基于防仿冒公钥/私钥 和搜寻者自己的公钥/私钥对, 配对尝试。

    • 提供程序处于配对模式。
    • 寻找者验证提供者是否拥有 防仿冒私钥

    请注意,在配对模式下,提供程序当然也可以在配对模式下 例如与不支持快速响应功能的设备配对 基于密钥的配对。

  • 案例 2:预共享密钥是账号密钥之一。

    • 提供程序通常不处于配对模式。(但这不是 要求—提供商应支持使用账号密钥,即使在 配对模式)。
    • 寻找者和提供者各自验证对方是否拥有 账号密钥。

由于这两种情况极其相似,除了使用预共享密钥之外, 它们会在程序中合并。

数据格式

如需了解每种格式的使用方法,请参阅过程

八位字节 数据类型 说明 是否必需?
0 - 15 uint128 已加密的请求 不定 强制
16-79 人 公钥 不定 可选

表 1.1:加密请求,由 Seeker 写入该特性。

八位字节 数据类型 说明 是否必需?
0 uint8 邮件类型 0x00 = 基于密钥的配对请求 强制
1 uint8 标志
  • 位 0 (MSB):已弃用并被 Seeker 忽略。
  • 位 1:1:如果查找器请求提供程序应发起绑定,并且此请求包含查找器的 BR/EDR 地址。否则为 0。
  • 位 2:1 如果搜寻者请求提供程序应通知现有姓名。否则为 0。
  • 位 3:1(如果是追溯写入账号密钥)。否则为 0。
  • 位 4 - 7 保留以供将来使用,并且应被忽略。
因人而异 强制
2 - 7 人 uint48 以下两个字段之一:
  • 提供商当前的 BLE 地址
  • 提供方的公开地址
因人而异 强制
8 - 13 人 uint48 寻找者的 BR/EDR 地址 因人而异 仅在已设置标志位 1 或 3 时显示
n - 15 随机值(盐) 因人而异 强制

表 1.2.1:原始请求(类型 0x00)。从已加密的 表 1.1 中的请求。

八位字节 数据类型 说明 是否必需?
0 uint8 邮件类型 0x10 = 操作请求 强制
1 uint8 标志
  • 位 0 (MSB):如果是设备操作,则为 1,否则为 0。
  • 位 1:如果后跟其他数据特征,则为 1,否则为 0。
  • 位 2 - 7 已预留供日后使用,并且应被忽略。
因人而异 强制
2 - 7 人 uint48 以下两个字段之一:
  • 提供商当前的 BLE 地址
  • 提供方的公开地址
因人而异 强制
8 uint8 邮件群组 因人而异 如果设置了标志位 0,则必须提供
9 uint8 邮件内容代码 因人而异 如果设置了标志位 0,则必须提供
10 uint8 取决于标记:
  • 已设置位 0:其他数据长度,小于 6
  • 已设置位 1:数据 ID
因人而异 如果设置了标志位 0 或 1,则必须提供
11 - n 附加数据 因人而异 可选
n - 15 随机值(盐) 因人而异 强制

表 1.2.2:原始请求(类型 0x10)。从已加密的 表 1.1 中的请求。

八位字节 数据类型 说明
0 uint8 邮件类型 0x01 = 基于密钥的配对响应
1 - 6 人 uint48 提供方的公开 (BR/EDR) 地址 因人而异
7-15 人 随机值(盐) 因人而异

表 1.3:原始响应。已加密以在 中生成 Encrypted Response 表 1.4.

八位字节 数据类型 说明
0 - 15 岁 uint128 加密响应 因人而异

表 1.4:由提供器通过 通知。

特征:通行密钥

此特性用于 基于密钥的配对 过程。

八位字节 数据类型 说明
0 - 15 uint128 已加密的通行密钥屏蔽设置 因人而异

表 2.1:加密通行密钥块。请参阅 使用基于密钥的配对过程。

八位字节 数据类型 说明
0 uint8 邮件类型 以下各项之一:
  • 0x02 = 搜寻者的通行密钥
  • 0x03 = 提供方的通行密钥
1 - 3 人 unit32 6 位数通行密钥 因人而异
4-15 人 随机值(盐) 因人而异

表 2.2:原始通行密钥块。 表 2.1 的解密版本。

特征:账号密钥

配对之后,快速配对搜寻者会向快速配对写入一个账号密钥 提供商。

八位字节 数据类型 说明
0 - 15 uint128 账号密钥(已加密) 因人而异

收到写入请求时,快速配对提供程序应执行以下操作:

  1. 使用在 流程
    • 对于需要绑定(通用)的提供商: <ph type="x-smartling-placeholder">
        </ph>
      • 在解密之前,请验证已使用共享密钥解密 第 12 步中的通行密钥请求。如果此步骤尚未通过 Secret,请忽略此写入并退出。
    • 此时,系统不会使用共享密钥(过程中的 K) 使用此密钥加密的所有请求 而不会重新开始该程序。
  2. 验证解密后的值是否以 0x04 开头。如果没有,则忽略 写入并退出。
  3. 检查保留的账号密钥列表是否有足够的空间存储新的 值。
  4. 如果不是,请从列表中删除最近最少使用的值。
  5. 将新值添加到列表中。

列表中的账号密钥会在基于密钥的配对期间使用。

特征:固件修订版本

此特性允许 Seeker 读取 提供商。它应始终返回以下数据:

八位字节 数据类型 说明
0 - 变量 utf8s 固件修订版本代码 因人而异

即使有多个 utf8 字符串,也应将其封装为单个 utf8 字符串 (例如,左侧耳机、右侧耳机和充电盒的 3 个固件)。 对于特殊情况,提供程序还可以返回特定字符串:

  1. status- updates:如果提供程序当前正在更新到新固件。 或者,提供程序也可以返回暂存固件的版本。

  2. status-abnormal:如果提供程序处于异常状态。例如, 因为固件更新失败而出现故障。该值会导致 Seeker 显示一条消息,让用户知道必须立即更新该消息。

提供商应将对固件修订版本特性的访问权限限制为 阻止设备跟踪。建议的限制:

  • 绑定的设备应该有权随时访问
  • 当提供程序可检测到时,任何设备都应该有权访问

特征:其他数据

此服务应具有以下特征。

快速配对服务特征 已加密 权限 UUID
数据 撰写和通知 FE2C1237-8366-4814-8EB0-01DE32100BEA
旧的快速配对服务特征(将于 2021 年 1 月 1 日弃用) 已加密 权限 UUID
数据 撰写和通知 0x1237

在编写或发出关于此特征的通知之前, 通过特征 FE2C1234-8366-4814-8EB0-01DE32100BEA 进行握手, 共享密钥。AES-CTR 将用于对流经此 其算法定义如下。此模式更 可跨越单个 16 字节的数据块确保安全。HMAC-SHA256 将 用于确保数据完整性,相关定义见下文。

八位字节 说明
0 - 7 HMAC-SHA256 的前 8 个字节。 因人而异
8-15 人 Nonce,用于 AES-CTR 加密。 因人而异
16 - 变量 加密的数据。 因人而异

表 3.1:提供程序通过 通过写入通知或发送给提供程序。

八位字节 数据类型 说明
0 - 变量 byte array 数据 ,则根据表 1.2.2 的数据 ID 进行解码:
  • 0x01(个性化名称):utf8s

表 3.2:原始数据。从以下项目的加密数据中解密: 表 3.1.

请求通知时(例如,通过 表 1.2.1),快速配对提供程序应执行以下操作:

  1. 为 Nonce 生成 8 个加密随机字节。
  2. 使用 AES-CTR 加密数据,其中每个 16 个字节的块都使用

    encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
    

    其中

    1. AES 密钥是过程中第 4 步中的共享密钥。
    2. clearBlock[i] 是一个从 data[i * 16] 开始的 16 字节块。最后一个 可以小于 16 个字节。
  3. 执行 concat(encryptedBlock[0], encryptionBlock[1],...) 创建 加密数据。

  4. HMAC-SHA256 的生成依据

    sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))
    

    其中

    1. K 由 concat(shared_secret, 48 字节 ZERO) 生成, shared_secret 将在过程中的第 4 步中找到。
    2. opad 是 64 个字节的外部填充,由输入的重复字节组成 0x5C
    3. ipad 是 64 个字节的内部填充,由输入的重复字节组成 0x36
  5. 将 HMAC-SHA256 中的前 8 个字节作为 Data 数据包

收到写入请求时,快速配对提供程序应执行以下操作:

  1. 通过检查 HMAC-SHA256。
  2. 使用 AES-CTR 解密已加密的数据,其中每个分块都使用

    clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
    

    其中

    1. EncryptBlock[i] 是一个以 encryption_data[i * 16] 开头的 16 字节块。 最后一个块可以小于 16 个字节。
    2. AES 密钥通过握手生成或识别,例如 <ph type="x-smartling-placeholder">
        </ph>
      1. 命名流程 1 中,它来自 ECDH,它不会 再次用于这一配对。所有以加密形式 在不重启程序的情况下使用此密钥, 已被拒绝。
      2. 命名流程 2 中,账号密钥是账号密钥。
  3. 执行 concat(clearBlock[0], clearBlock[1],...) 创建原始数据。