如何在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
相关产品推荐
相关产品推荐

