返回首页

BLE 安全学习笔记

1. BLE 安全概述

1.1 安全威胁

1.2 安全特性

2. BLE 配对流程

2.1 配对模式

// 设置 IO 能力
io_capability = BLE_IO_CAP_IN_PASSKEY_DISPLAY;

// 选择配对模式
// LE Legacy Pairing: 传统配对
// LE Secure Connections: 安全配对(SC)

2.2 配对方法

方法MITM 保护密钥生成
Just Works128-bit
Passkey Entry128-bit
OOB128-bit
Numeric Comparison128-bit

2.3 配对流程

1. 发起配对请求
2. 交换 IO 能力
3. 选择认证算法
4. 生成密钥
5. 分发密钥
6. 配对完成

3. SMP 协议

3.1 SMP 状态机

// SMP 状态
typedef enum {
    BLE_SMP_STATE_IDLE,       // 空闲
    BLE_SMP_STATE_PAIRING,   // 配对中
    BLE_SMP_STATE_BONDED,    // 已绑定
} ble_smp_state_t;

3.2 密钥类型

3.3 密钥分发

// 分发 LTK
struct smp_key_dist_flags key_dist;
key_dist.dist_ltk = 1;
key_dist.dist_irk = 1;
key_dist.dist_csrk = 1;

4. 加密连接

4.1 LE Secure Connections

// 启用安全连接
int ble_secURITY_set_level(uint16_t conn_handle, uint8_t level) {
    switch(level) {
        case BLE_SECURITY_LEVEL_1: // 无安全
            break;
        case BLE_SECURITY_LEVEL_2: // 加密连接
            break;
        case BLE_SECURITY_LEVEL_3: // 认证配对
            break;
        case BLE_SECURITY_LEVEL_4: // MITM 保护
            break;
    }
}

4.2 加密参数

struct ble_gap_lesc_p256_pk {
    uint8_t x[32];
    uint8_t y[32];
};

// DH 密钥交换
ecdh_p256_generate_key(&public_key, &private_key);

5. 绑定与存储

5.1 Bonding

// 保存绑定信息
int ble_store_bonding(uint16_t conn_handle, 
                      struct ble_gap_sec_params *params) {
    // 存储 LTK, IRK, CSRK
    ble_gap_sec_params_store(params);
}

5.2 密钥存储

// NVS 存储密钥
int save_keys(struct ble_dev_keys *keys) {
    settings_save("ble/keys", keys, sizeof(*keys));
}

6. 隐私保护

6.1 地址类型

6.2 隐私模式

// 启用隐私
int ble_privacy_enable(uint16_t conn_handle) {
    // 使用 IRK 生成可解析私有地址
    generate_resolvable_address(irk, &addr);
}

6.3 地址解析

// 解析 RPA
int resolve_address(uint8_t *addr, uint8_t *irk) {
    // SHA-256 hash 验证
    return verify_prand(addr, irk);
}

7. Zephyr BLE 安全 API

7.1 安全配置

// Kconfig 配置
CONFIG_BT_SMP=y
CONFIG_BT_PRIVACY=y

// 设置安全模式
bt_conn_auth_info_cb_register(&auth_info_cb);

7.2 配对请求处理

static uint8_t smp_passkey_entry(struct bt_conn *conn) {
    uint8_t err;
    uint32_t passkey = 123456;
    
    err = bt_conn_auth_passkey_entry(conn, passkey);
    return err;
}

7.3 安全连接

// 请求安全连接
int request_security(struct bt_conn *conn) {
    return bt_conn_security(conn, BT_SECURITY_L4);
}

8. 常见攻击与防护

8.1 攻击类型

8.2 防护措施

// 请求更高安全级别
if (bt_conn_security(conn, BT_SECURITY_L4) != 0) {
    return -EACCES;
}

9. 调试与测试

9.1 nRF Connect 验证

9.2 日志调试

// 启用安全日志
CONFIG_BT_DEBUG_SMP=y

10. 最佳实践

  1. 始终使用 LE Secure Connections
  2. 强制 MITM 保护
  3. 定期轮换密钥
  4. 启用隐私保护
  5. 验证设备身份

参考资料