You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows上建立不触发SMP的BLE连接?解决密钥缺失断开问题

解决方案:避免Windows BLE连接触发SMP加密及密钥缺失报错

1. 清除Windows端的配对缓存

Windows会保留已配对设备的密钥缓存,即使手机端解除配对,PC仍会尝试用旧密钥发起加密。先清除缓存再重新连接:

// 获取蓝牙设备ID(通过扫描或设备枚举得到)
string deviceId = "蓝牙设备的ID字符串";
BluetoothDevice device = await BluetoothDevice.FromIdAsync(deviceId);
if (device != null)
{
    // 移除设备,清除配对缓存
    await device.RemoveDeviceAsync();
    // 重新获取设备并发起连接
    device = await BluetoothDevice.FromIdAsync(deviceId);
    // 后续执行GATT服务获取等操作
}

2. 使用Win32低级别蓝牙API控制连接加密

如果UWP的GATT API无法满足需求,可以直接调用Win32的蓝牙LE连接函数,明确指定不加密的连接参数:

// 示例:使用Win32的BthLEConnect函数,设置连接不加密
BLUETOOTH_LE_CONNECT_PARAMS connectParams = {0};
connectParams.dwSize = sizeof(BLUETOOTH_LE_CONNECT_PARAMS);
connectParams.hRadio = hRadio; // 蓝牙适配器句柄
connectParams.Address = deviceAddress; // 目标设备蓝牙地址
connectParams.EncryptionRequired = FALSE; // 禁用加密要求
connectParams.ConnectionInterval = 0; // 使用默认间隔
connectParams.SupervisionTimeout = 0; // 使用默认超时

HRESULT hr = BthLEConnect(&connectParams);

注意:使用Win32 API需要申请蓝牙相关权限(如bluetooth权限),且需要处理设备枚举、适配器句柄获取等前置步骤。

3. 调整安卓端BLE服务的安全属性(若可控制设备端)

如果安卓设备的BLE服务/特征被标记为需要加密(如SECURITY_AUTHENTICATED或SECURITY_ENCRYPTED),Windows会强制触发SMP加密流程。修改安卓端代码,将服务的安全等级设为NO_SECURITY:

// 安卓端设置BLE服务安全等级
BluetoothGattService service = new BluetoothGattService(UUID.fromString("你的服务UUID"), BluetoothGattService.SERVICE_TYPE_PRIMARY);
service.setCharacteristicPermissions(BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
// 设置特征的安全属性为无加密
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(UUID.fromString("你的特征UUID"), 
    BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
    BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
service.addCharacteristic(characteristic);

这样Windows连接时不会触发加密要求,自然不会出现密钥缺失问题。

4. 强制设置GATT会话的权限级别

在获取GattSession后,手动设置会话的权限状态,允许无加密访问:

GattSession session = GattSession.FromDeviceId(deviceId);
if (session != null)
{
    // 设置权限为允许,不要求加密
    session.SetSessionPermissionStatus(deviceId, GattSessionPermissionStatus.Allow);
    // 维持连接
    session.MaintainConnection(true);
}

注意:此方法需要确保设备端的服务/特征没有强制加密要求,否则Windows仍会触发加密流程。

内容的提问来源于stack exchange,提问作者xiansen c

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:32:16