Passkey 配对
BLE SMP Passkey Entry
前置阅读:Just Works 配对
学习目标
- 理解 Passkey Entry 与 Just Works 的核心区别——6 位 PIN 防 MITM
- 掌握 Peripheral 显示 PIN / Central 输入 PIN 的两种模式
- 理解 Passkey 在 SMP 配对 Phase 2 中的作用
规格与功能
Peripheral 生成 6 位随机 PIN(通过串口打印),Central 端读取串口输入的 PIN 完成配对。配对成功后 Bonding,重连自动恢复加密。
基本概念
Passkey 如何防 MITM
Just Works 的 TK 固定为 000000,攻击者可以拦截并解密通信。Passkey Entry 的 TK = 用户输入的 6 位 PIN(如 123456),攻击者不知道 PIN 就无法计算 STK,MITM 被阻断。
IO Capability 组合
| Peripheral | Central | 配对模式 |
|---|---|---|
| NoInputNoOutput | NoInputNoOutput | Just Works |
| DisplayOnly | KeyboardOnly | Passkey(Peripheral 显示,Central 输入) |
| KeyboardOnly | DisplayOnly | Passkey(Central 显示,Peripheral 输入) |
| DisplayYesNo | KeyboardOnly | Numeric Comparison(双方确认 6 位数字) |
涉及 API
| API | 谁调用 | 用途 |
|---|---|---|
gap_ble_set_io_cap(DISPLAYONLY) |
Peripheral | 设置显示能力 |
gap_ble_set_io_cap(KEYBOARDONLY) |
Central | 设置输入能力 |
gap_ble_passkey_display_rsp() |
Peripheral | 回应显示的 Passkey |
gap_ble_passkey_input_rsp() |
Central | 回应输入的 Passkey |
gap_ble_security_req() |
Central | 发起配对 |
案例操作指导
Peripheral 串口打印 Passkey: 123456。Central 端读取此 PIN,输入后配对成功。
关键配置
- Peripheral IO Capability:
DISPLAYONLY - Central IO Capability:
KEYBOARDONLY - Bonding:启用
代码详解
Peripheral 端
gap_ble_set_io_cap(DISPLAYONLY);
// Passkey 显示回调 — 协议栈生成随机 PIN
static void passkey_display_cb(uint16_t conn_id, uint32_t passkey)
{
printf("Passkey: %06u\n", passkey); // 串口打印,用户看到后输入 Central
gap_ble_passkey_display_rsp(conn_id, true); // 确认显示
}
Central 端
gap_ble_set_io_cap(KEYBOARDONLY);
// Passkey 输入回调 — 用户在 Central 串口输入 PIN
static void passkey_input_req_cb(uint16_t conn_id)
{
uint32_t passkey = read_passkey_from_serial(); // 从串口读取用户输入的 PIN
gap_ble_passkey_input_rsp(conn_id, passkey);
}
BLE 配对方式选择指南
| 你的设备 | 推荐 |
|---|---|
| 无显示、无输入(传感器/网关) | Just Works |
| 有显示、无输入(带屏幕的设备) | Passkey Entry (Display) |
| 无显示、有输入(带按键的设备) | Passkey Entry (Keyboard) |
| 有显示、有输入(带触摸屏) | Numeric Comparison |