hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.74k stars 292 forks source link

Problem to pair to a BLE Server having encrypted(authenticated) read/write characteristics in Python/Linux? #758

Open hientv1999 opened 2 years ago

hientv1999 commented 2 years ago

Description

In the documentation of Bleak, there isn't any information about pairing with BLE server required authentication/encryption in Linux. I only found pair() under class bleak.backends.winrt.client.BleakClientWinRT for Windows, but I'm using Linux and it didn't work.

What I Tried

I'm essentially sending data from ESP32 as a BLE server to Raspberry Pi as a BLE client. I want the data to be encrypted. Here is my characteristics defining for ESP32 in void setup().

    BLEDevice::init(sensorName);
    NimBLEDevice::setPower(ESP_PWR_LVL_P9);
    NimBLEDevice::setSecurityAuth(true, true, true);
    NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT);
    NimBLEServer *pServer = NimBLEDevice::createServer();
    NimBLEService *pService = pServer->createService(SERVICE_UUID);
    NimBLEService *pService2 = pServer->createService(SERVICE_UUID2);
    pCharacteristic = pService->createCharacteristic(beb5483e-36e1-4688-b7f5-ea07361b26a8, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_ENC );
    pCharacteristic2 = pService2->createCharacteristic(42eab6ec-829e-4d99-b48f-81481d077948, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC);
    pService->start();
    pService2->start();
    NimBLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
    pAdvertising->setMinPreferred(0x12);
    NimBLEDevice::startAdvertising();

The BLE Server works well when I used LightBlue app on iPhone to connect to it and write/read all characteristics from it is good. However, Raspberry Pi using Bleak cannot read/write to any read_enc and write_enc characteristic. Below is the code I used in Raspberry Pi.

from bleak import BleakClient
import time, asyncio
async def main():
        client = BleakClient("my_address")
            start = time.time()
            while time.time() - start < float(60):
                try:
                    await client.connect()
                    await client.write_gatt_char("my_char",bytearray("my_data","utf-8"),response=True)
                    await client.disconnect()
                except Exception as e:
                    print(e)
                    await asyncio.sleep(0.1)
                else:
                    break
 asyncio.run(main())

The error output

Characteristic beb5483e-36e1-4688-b7f5-ea07361b26a8 does not support write operations!

What I tried more

I also attempted to add await client.pair(2) right after await client.connect() but it doesn't help. Please help me know if there is any workaround to utilize the encryption (and potentially authentication) feature of BLE. Since I'm transmitting WiFI SSID and Passkey, I need to keep the transfer very secure.

Important note

If I just define the characteristics in ESP32 as write and read (without encryption), everything will work fine. Raspberry Pi using Bleak can send/receive data from ESP32 with no sweat.

A bit out-of-topic question

This is a question more related to merely BLE and slightly ESP32. In ESP32 code, this line NimBLEDevice::setSecurityAuth(true, true, true); enables bonding, man in the middle protection and secure connection pairing. I'm more interested in MIMP. If I don't have WRITE_ENC and READ_ENC (meaning I use only normal WRITE and READ for characteristics), is data still protected against MIM attack?

bojanpotocnik commented 1 year ago

@hientv1999 at that time the pairing was not yet well supported, but if still relevant, you can try again using latest releases (Just Works pairing is supported there) or branches from https://github.com/hbldh/bleak/pull/1100 or https://github.com/hbldh/bleak/pull/1133 if advanced pairing methods are used.