1. 問題現象與核心背景

在 Windows 10/11 平台下開發基於 Bleak 庫的藍牙低功耗 (BLE) 通訊網關時,針對特定客製化服務特徵點(例如 00004571 監聽通道),系統在未進行安全通訊升級前會觸發底層中斷,拋出以下標準 GATT 協議錯誤:

  • GATT Protocol Error: Insufficient Authentication (5)
  • GATT Protocol Error: Insufficient Encryption (15)

然而,在調用通道安全升級函數 await client.pair(protection_level=1) 後,程式雖然能繞過權限限制並成功註冊 Notify 監聽,但主機端(Windows 系統)卻完全沒有彈出任何要求輸入配對密碼 (PIN Code) 的視窗。即使更換至全新、從未連線過的電腦設備,該現象依然存在。

2. 藍牙 LE 安全機制底層原理分析

BLE 的安全安全性設定分為安全模式 (Security Mode) 與安全等級 (Security Level),其認證流程取決於中央端(主機)與周邊端(晶片韌體)在 GAP (Generic Access Profile) 層的動態協商。

2.1 為什麼能「無密碼」註冊加密通道

當主機端調用安全配對請求時,底層的加密鏈結建立取決於韌體端配置的 配對模式 (Pairing Mode)。 本案例中,特徵點雖然被設定為「需要加密連線」,但晶片韌體的安全參數應該是配置了 Just Works (直接配對) 模式。其內部交握邏輯如下:

  1. 主機端發起請求:Python 腳本透過 Windows API 發出 pair(protection_level=1),要求將當前 L2CAP 通道提升至加密狀態。
  2. 金鑰交換層級:Windows 藍牙堆疊接收到晶片「無輸入輸出能力」的宣告後,判定無法進行密碼比對,因此自動調用 Just Works 機制,在背景直接完成藍牙身份驗證。
  3. 通道狀態:通道成功被加密,Windows 認為安全合規,進而放行對特徵點的讀寫與監聽權限,導致最終無任何密碼彈窗。

3. Windows 系統層級的隱形快取 (Ghost Cache) 機制

在排查過程中發現,即使在作業系統的「藍牙與其他裝置」設定介面中找不到該藍牙設備(顯示為未配對狀態),微軟底層的藍牙驅動仍可能殘留該裝置的歷史配對金鑰快取。

  • 快取成因:當透過第三方非系統內置工具(如 Bluetooth LE Explorer 或未完全釋放實體鎖的 Python 腳本)進行連線與配對時,Windows 會將其歸類為應用層臨時快取,而非系統級常駐配對設備。
  • 快取異常:若此隱形快取中的金鑰安全層級,與晶片韌體後續變更或要求的層級不一致時,主機會直接使用舊金鑰進行交握,導致晶片端拒絕通訊,拋出 Insufficient Encryption 錯誤,且系統因認為金鑰存在而拒絕重新觸發配對。
  • 程式端解法:在建立正式連線前,必須透過獨立的、無連線佔用的客戶端物件顯式調用 await client.unpair(),強制沖刷 Windows 核心層的設備快取暫存,才能確保通道狀態完全重置。

4. 韌體端安全性防禦漏洞與修正方案

目前的配置雖能達成通訊,但在商業與工業應用中存在嚴重的安全漏洞:任何第三方設備只需發起標準的配對請求,即可在不需要通過任何物理或密碼驗證的情況下,直接讀取與監聽內部敏感的暫存器數據。

若要強制 Windows 彈出系統通知並要求手動輸入指定配對碼(例如 123456),晶片韌體工程師必須於代碼中修正 GAP 與 GATT 的安全配置:

4.1 啟用 MITM 保護

在藍牙協議棧初始化與配對參數配置中,必須將中間人保護 (Man-In-The-Middle Protection) 宣告為啟用。

  • 參數範例:MITM = True 或 LE_GAP_AUTH_KEY_REQ_MITM

4.2 修正 IO Capabilities (重要)

將晶片的 IO 能力從 NoInputNoOutput 修改為具備顯示能力的模式,迫使兩端協議棧無法採用 Just Works 進行背景自動配對。

  • 修正配置:DisplayOnly (唯顯示) 或 KeyboardDisplay
  • 行為變更:當宣告為 DisplayOnly 時,晶片在配對時會生成或使用固定的密碼,Windows 接收到此宣告後,便會依法強制跳出 PIN 碼輸入對話框。

4.3 提升特徵點安全權限

確認客製化通訊服務中的特徵點讀寫權限,使用的是需要經過授權的安全層級。

  • 權限配置:SEC_MITM / ENCRYPT_WITH_MITM / Authenticated Read/Write

5. 結論與後續排查檢查清單

  1. 網關程式狀態:當前 Python (Bleak) 網關架構中的 unpair() 重置快取流程與 pair(protection_level=1) 通道升級代碼完全正確,且符合微軟 UWP 藍牙底層設計規範。
  2. 通訊超時原因:在安全通道成功建立且 Notify 成功註冊後,出現的發送控制命令超時無回應 (Timeout),確認為測試晶片內部尚未實作 BMS 協議暫存器的回傳邏輯(晶片接收數據後未進行 Notify 寫回)。
  3. 驗證步驟:待韌體工程師修正 GAP 認證層級(開啟 MITM 與修改 IO 能力)後,可重新跑通程式,屆時系統將完美觸發預期的密碼安全驗證。