2

我正在为 FIDO2 构建一个 Android 身份验证器。我被读/写特性卡住了。我正在使用 Mac - Chrome 75。Chrome 可以检测到我的 Android BLE 身份验证器。在检测到我的 BLE Authenticator 后,onCharacteristicReadRequest()从验证器端调用。在里面onCharacteristicReadRequest()我正在使用下面编写的代码,但之后没有来自客户端的响应。

我已经尝试过版本为 0b01000000 的 U2F。它工作正常。当我移动 FIDO2 版本 0b100000 时,我遇到了这个问题。我正在从身份验证器宣传 fido 服务和设备信息服务。这两个服务都添加了 Thread.sleep(1000) 间隔。我无法按顺序添加这两项服务。当我按顺序添加这两个服务时,我得到ArrayIndexOutofBoundException.

我不知道这两个问题是否相互关联。如果我做错了什么,请纠正我。

{
...
}else if (characteristic.getUuid().equals(FidoUUIDConstants.FIDO_SERVICE_REVISION_BITFIELD)) {
    status = BluetoothGatt.GATT_SUCCESS;
    ByteBuffer bb = ByteBuffer.allocate(1);
    bb.order(ByteOrder.BIG_ENDIAN);
    bb.put((byte) (1 << 5));
    bytes = bb.array();
}
mGattServer.sendResponse(device, requestId, status, 0, bytes);

客户端应在预期 fidoServiceBitFieldversion 之后读取/写入特征。

4

3 回答 3

2

我无法按顺序添加这两项服务

我认为您可以添加device info service以下内容:

gattServer = bleManager.openGattServer(this, new BluetoothGattServerCallback() {
    @Override
    public void onServiceAdded(int status, BluetoothGattService service) {
        if (service.getUuid().equals(FidoUUIDConstants.FIDO2_GATT_SERVICE)) {
            gattServer.addService(deviceInfoService);
        }
    }
});
gattServer.addService(fido2GattService)

对于特性fidoServiceRevisionBitfield,我只是简单地在CTAP 文档a device that only supports FIDO2 Rev 1 will only have a fidoServiceRevisionBitfield characteristic of length 1 with value 0x20.的索引8.3.5.1. FIDO Service处遵循了这个声明。因此,我的实现是:

if(characteristic.getUuid().equals(FIDO2GattService.SERVICE_REVISION_BITFIELD)) {
    status = BluetoothGatt.GATT_SUCCESS;
    bytes = new byte[] {0x20}
}
gattServer.sendResponse(device, requestId, status, 0, bytes);
于 2019-06-11T16:52:49.160 回答
2

您应该覆盖 BluetoothGattServerCallback 的所有方法

我认为您缺少 onDescriptorReadRequest、onDescriptorWriteRequest 实现。

@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
    if (descriptor.getCharacteristic().getUuid().equals(FIDO2GattService.CONTROL_POINT_UUID) &&
            descriptor.getUuid().equals(FIDO2GattService.CONTROL_POINT_DESCRIPTOR_UUID)) {
        gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[] {0x31, 0x2e, 0x32});
    } else {
        gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[] {0x00, 0x00});
    }
}
@Override
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
    gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
}
于 2019-06-12T14:41:17.173 回答
2

我同意@Bao 的关注。根据 CTAP 规范,您应该定义与具有 READ/WRITE 权限的每个特征对应的描述符。请注意,每个描述符的 UUID 都需要有效的 UUID 128 位格式。所有描述符都具有 READ 和 WRITE 权限。例如:

UUID CONTROL_POINT_DESCRIPTOR_UUID = UUID.fromString("00002901-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor controlPointDescriptor = new BluetoothGattDescriptor(
    CONTROL_POINT_DESCRIPTOR_UUID,
    BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE
);
于 2019-06-15T10:30:39.223 回答