特性
快速配對服務
快速配對供應商應具備下列 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 | 各異 |
特性:以金鑰為準的配對
這項特徵會控管以金鑰為準的配對程序。在這個程序中,系統會驗證 Seeker 和 Provider 是否都擁有預先共用金鑰,藉此建立一定程度的信任。每個案例的鍵都不同:
情況 1:預先共用金鑰是以防偽公開/私密金鑰組為基礎,以及 Seeker 自己的公開/私密金鑰組,每次嘗試配對時都會變更。
- Provider 處於配對模式。
- Seeker 會驗證 Provider 是否擁有防偽私密金鑰。
請注意,在配對模式下,供應商當然也可以透過一般方式配對,例如與不支援快速配對金鑰配對的裝置配對。
案例 2:預先共用金鑰是帳戶金鑰之一。
- Provider 通常不會處於配對模式。(但這並非必要條件,即使處於配對模式,提供者也應支援使用帳戶金鑰)。
- 「尋找者」和「提供者」各自驗證對方是否擁有帳戶金鑰。
由於這兩種情況極為相似,只有使用的預先共用金鑰不同,因此會合併在程序中。
資料格式
如要瞭解每種格式的使用方式,請參閱程序。
| 八位元 | 資料類型 | 說明 | 值 | 是否為必填欄位? |
|---|---|---|---|---|
| 0 - 15 | uint128 |
加密要求 | 各異 | 必填 |
| 16 - 79 | 公開金鑰 | 各異 | 選用 |
表 1.1:加密要求,由 Seeker 寫入特徵。
| 八位元 | 資料類型 | 說明 | 值 | 是否為必填欄位? |
|---|---|---|---|---|
| 0 | uint8 |
訊息類型 | 0x00 = 以金鑰為準的配對要求 |
必填 |
| 1 | uint8 |
旗標
|
因人而異 | 必填 |
| 2 - 7 | uint48 |
符合以下任一條件:
|
因人而異 | 必填 |
| 8 - 13 | uint48 |
搜尋者的 BR/EDR 地址 | 因人而異 | 只有在設定 Flags Bit 1 或 3 時才會顯示 |
| n - 15 | 隨機值 (鹽) | 因人而異 | 必填 |
表 1.2.1:原始要求 (類型 0x00)。從 表 1.1 中的加密要求解密。
| 八位元 | 資料類型 | 說明 | 值 | 是否為必填欄位? |
|---|---|---|---|---|
| 0 | uint8 |
訊息類型 | 0x10 = 動作要求 |
必填 |
| 1 | uint8 |
旗標
|
因人而異 | 必填 |
| 2 - 7 | uint48 |
符合以下任一條件:
|
因人而異 | 必填 |
| 8 | uint8 |
訊息群組 | 因人而異 | 如果設定了旗標位元 0,則為必填 |
| 9 | uint8 |
訊息代碼 | 因人而異 | 如果設定了旗標位元 0,則為必填 |
| 10 | uint8 |
取決於旗標:
|
因人而異 | 如果設定了旗標位元 0 或 1,則為必要欄位 |
| 11 - n | 額外資料 | 因人而異 | 選用 | |
| n - 15 | 隨機值 (鹽) | 因人而異 | 必填 |
表 1.2.2:原始要求 (類型 0x10)。從 表 1.1 中的加密要求解密。
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 | uint8 |
訊息類型 | 0x01 = 根據金鑰配對的回覆 |
| 1 - 6 | uint48 |
供應商的公開 (BR/EDR) 位址 | 因人而異 |
| 7 - 15 | 隨機值 (鹽) | 因人而異 |
表 1.3:原始回應。加密,以產生表 1.4 中的加密回應。
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 到 15 分鐘 | uint128 |
加密回覆 | 因人而異 |
表 1.4:加密回應,由供應商透過通知傳送給搜尋者。
特徵:密碼金鑰
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 - 15 | uint128 |
加密密碼金鑰區塊 | 因人而異 |
表 2.1:加密密碼金鑰區塊。如要瞭解如何使用,請參閱「以金鑰為準的配對程序」。
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 | uint8 |
訊息類型 | 下列任一項:
|
| 1 到 3 人 | unit32 |
6 位數密碼金鑰 | 因人而異 |
| 4 - 15 | 隨機值 (鹽) | 因人而異 |
表 2.2:原始密碼金鑰區塊。 表 2.1 的解密版本。
特徵:帳戶金鑰
配對完成後,快速配對搜尋器會將帳戶金鑰寫入快速配對供應商。
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 - 15 | uint128 |
帳戶金鑰 (已加密) | 因人而異 |
收到寫入要求後,快速配對供應商應執行下列操作:
- 使用程序中步驟 4 產生的共用密鑰,解密帳戶金鑰。
- 需要綁定 (常見) 的供應商:
- 解密前,請確認共用密鑰已用於解密步驟 12 中的密碼金鑰要求。如果使用這個密鑰未通過這個步驟,請忽略這次寫入並結束。
- 此時,系統不會再使用共用密鑰 (程序中的 K) 進行配對。如果要求使用這個金鑰加密,但未重新啟動程序,就應拒絕。
- 需要綁定 (常見) 的供應商:
- 確認解密值開頭為
0x04或0xFF。如果不是,請忽略這次寫入作業並結束。- 如果值為
0x04:- 檢查持續性 Account Key 清單是否有空間容納新值。
- 如果沒有,請從清單中刪除近期最少使用的值。
- 將新值新增至清單。
- 如果值為
0xFF:
- 如果值為
清單中的帳戶金鑰會在以金鑰配對時使用。
特徵:韌體修訂版本
這項特徵可讓 Seeker 視需要讀取 Provider 的韌體修訂版本。一律應傳回下列資料:
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 - var | utf8s |
韌體修訂代碼 | 因人而異 |
即使供應商提供多個韌體 (例如左耳機、右耳機和充電盒各 3 個韌體),也應封裝成單一 utf8 字串。供應商也可以針對特殊情況傳回特定字串:
status-updating:如果供應商目前正在更新韌體。 或者,供應商可以傳回暫存韌體版本。
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 | AES-CTR 加密使用的 Nonce。 | 因人而異 |
| 16 - var | 加密資料。 | 因人而異 |
表 3.1:資料封包,由供應商透過通知傳送給搜尋者,或由搜尋者透過寫入傳送給供應商。
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 - var | byte array |
資料 | 而有所不同,請根據表 1.2.2 的資料 ID 解碼:
|
表 3.2:原始資料。從 表 3.1 中的加密資料解密。
要求通知時 (例如透過表 1.2.1 中的 Bit 2 要求個人化名稱),快速配對供應商應執行下列操作:
- 為 Nonce 產生經過加密的隨機 8 位元組。
使用 AES-CTR 加密資料,其中每個 16 位元組的區塊都是使用以下方式產生:
encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))媒介
- AES 金鑰是程序步驟 4 中的共用密鑰。
- clearBlock[i] 是從 data[i * 16] 開始的 16 位元組區塊。最後一個區塊的長度可以小於 16 個位元組。
執行 concat(encryptedBlock[0], encryptedBlock[1],...),建立加密資料。
透過下列方式產生 HMAC-SHA256:
sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))媒介
- K 是由 concat(shared_secret, 48 位元組的零) 產生,而 shared_secret 來自程序的步驟 4。
- opad 是 64 位元組的外部填補,由值為
0x5C的重複位元組組成。 - ipad 是 64 個位元的內部填補,由值為
0x36的重複位元組成。
從 HMAC-SHA256 中取出前 8 個位元組,做為資料封包的前置字元。
收到寫入要求後,快速配對供應商應執行下列操作:
- 檢查 HMAC-SHA256 的前 8 個位元組,驗證資料完整性。
使用 AES-CTR 解密加密資料,其中每個區塊都是使用
clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))媒介
執行 concat(clearBlock[0], clearBlock[1],...) 建立原始資料。