11.13. Párování a vázání (bonding)

Vše, co jsme dosud probrali, přenáší bajty rádiem v otevřené podobě. Kdokoli s notebookem podporujícím BLE ve stejné místnosti může poslouchat na advertising kanálech, sledovat sekvenci přeskakování otevřeného spojení a přečíst si každé čtení, zápis a notifikaci, které proběhnou. Pro většinu veřejných senzorových dat (úroveň baterie, okolní teplota) to nevadí. U čehokoli, co chtějí oba koncové body udržet v soukromí – řídicí registr, který aktivuje relé, heslo, měření, jež by se nemělo široce vysílat – je potřeba spojení zašifrovat a ideálně by kamera měla vědět, s kým komunikuje.

BLE poskytuje obojí prostřednictvím párování a vázání (bonding).

11.13.1. Párování, vázání, šifrování

Tři úzce související pojmy:

  • Šifrování je hlavní cíl. Jakmile je spojení zašifrované, každý paket na datových kanálech mohou rozšifrovat pouze oba koncové body; odposlouchávající vidí jen šum.

  • Párování je procedura, kterou oba koncové body provedou, aby se dohodly na klíčích, které šifrování používá. Je to jednorázová výměna, jež vytvoří sdílený klíčový materiál, který linková vrstva zapojí do svého šifrovacího mechanismu.

  • Vázání (bonding) je rozhodnutí uchovat klíče v energeticky nezávislém úložišti po dokončení párování, takže příští spojení mezi týmiž dvěma zařízeními přeskočí párování a přejde rovnou k šifrování.

Jednoduše řečeno: párování je „představte se navzájem“; vázání je „zapamatuj si toto představení“; šifrování je „od teď spolu mluvte v soukromí“.

Dva sloupce označené „Central“ a „Peripheral“. Čárkovaná čára blízko vrcholu označená „BLE spojení otevřeno (nešifrované)“. Pod ní tři šipky: „požadavek na párování“ od central k peripheral, „výměna klíčů“ oběma směry, „párování dokončeno“ dopředu. Druhá čárkovaná čára níže označená „spojení zašifrováno“. Dvě tlusté obousměrné šipky nesou „šifrovaný GATT provoz“. Volitelný box „ulož klíče do flash“ na straně, označený „vázání“.

Průběh párování nad otevřeným BLE spojením. Jakmile se výměna klíčů dokončí, linková vrstva šifruje každý následující paket. Vázání je krok navíc spočívající v zápisu klíčů do flash paměti.

11.13.2. LE Secure Connections

Moderní výměna klíčů používaná v BLE se nazývá LE Secure Connections a je postavena na Elliptic Curve Diffie-Hellman. Obě strany vygenerují dočasný pár klíčů, vymění si veřejné poloviny a zkombinují výsledek se svými vlastními soukromými klíči, čímž dospějí ke stejnému sdílenému tajemství – tajemství, které odposlouchávající nedokáže vypočítat ani s úplným záznamem výměny.

Starší metoda LE Legacy je méně bezpečná (odposlouchávající s úplnou výměnou obvykle dokáže klíč obnovit) a existuje pouze kvůli zpětné kompatibilitě se starými periferiemi. Výchozí volbou v aioble je moderní metoda (le_secure=True); ponechte ji.

11.13.3. Zahájení párování

Central zahájí párování voláním aioble.DeviceConnection.pair() na již otevřeném spojení:

async with await device.connect() as connection:
    await connection.pair(bond=True, le_secure=True, mitm=False)
    # ... GATT work, now over an encrypted link ...

Poté, co se pair vrátí, atributy encrypted, authenticated, bonded a key_size na spojení odrážejí, co bylo vyjednáno.

Čtyři nejužitečnější pojmenované argumenty:

  • bond=True – uloží výsledné klíče do flash paměti, takže příští spojení mezi týmiž dvěma zařízeními přeskočí párovací handshake. Výchozí hodnota True.

  • le_secure=True – použije LE Secure Connections. Výchozí hodnota True. Ponechte zapnuté.

  • mitm=False – zda vyžadovat ochranu proti man-in-the-middle. To vyžaduje out-of-band kanál (číselný kód zobrazený na jedné straně a potvrzený na druhé, zadaný přístupový klíč, …), aby uživatel mohl ověřit, že dvě zařízení v párovacím handshake jsou skutečně ta, za která je považuje. Výchozí hodnota je False (žádná ochrana MITM – pasivní odposlouchávající nemůže spojení přečíst, ale útočník aktivně přesměrovávající spojení by se mohl do párování vmísit). Pro cokoli citlivého nastavte na True, ale mějte na paměti, že to vyžaduje, aby periferie skutečně podporovala nějakou IO schopnost.

  • io=3 – IO schopnost, kterou zařízení deklaruje. Specifikace Bluetooth jich definuje pět: 0 pouze displej, 1 displej + ano/ne, 2 pouze klávesnice, 3 žádný vstup, žádný výstup, 4 klávesnice + displej. Kamera bez uživatelského rozhraní typicky hlásí 3; pokud má kamera samotná displej, aplikace by mohla zobrazit číselné potvrzení a použít 1. Kombinace IO schopností obou stran rozhoduje, zda je dosažitelná skutečná ochrana MITM.

Periferie samy nevolají pair – reagují na to, co iniciuje central. Zda je pro danou charakteristiku vyžadováno šifrování, je vlastností způsobu, jakým je deklarována v databázi GATT; přístupové bity vyžadující šifrování jsou součástí nízkoúrovňového API bluetooth a aktuálně nejsou skrze konstruktor charakteristiky v aioble zpřístupněny.

11.13.4. Vázání – a kde klíče žijí

Když je bond=True, aioble zapíše klíče do souboru JSON na lokálním souborovém systému. Výchozí název souboru je ble_secrets.json, zapisovaný relativně k aktuálnímu pracovnímu adresáři. Na čerstvě nabootované kameře už _boot.py tento adresář zvolil: /sdcard, je-li připojena karta, jinak /flash – soubor tedy skončí v /sdcard/ble_secrets.json nebo /flash/ble_secrets.json. Soubor obsahuje záznamy potřebné k opětovnému zašifrování spojení, až se vázaný protějšek příště znovu připojí, včetně identitní adresy protějšku.

Jednu asymetrii je třeba mít na paměti: ukládání probíhá automaticky s tím, jak se klíče mění, ale načtení souboru při příštím bootu nikoli. Zavolejte aioble.security.load_secrets() jednou při startu (před jakýmkoli párováním nebo advertisingem), aby byly dříve vázané protějšky rozpoznány:

import aioble
aioble.security.load_secrets()        # default path: ble_secrets.json

Poté, až se příště objeví vázaný protějšek, aioble znovu použije uložené klíče a spojení se zašifruje bez dalšího handshaku.

Dva praktické důsledky ukládání klíčů na flash:

  • Zapomenutí zařízení. Smažte ble_secrets.json (nebo odstraňte příslušný záznam), abyste zapomněli všechny vázané protějšky, a poté se spárujte znovu od začátku.

  • Fyzický přístup vyzradí klíče. Kdokoli s přístupem k souborovému systému kamery si může JSON přečíst. Je to stejný druh omezení, který se objevil na síťové straně u TLS klíčů (Provoz: klíče, expirace a řešení potíží): používejte klíče pro jednotlivá zařízení, považujte každý uložený klíč za obnovitelný a spoléhejte na schopnost odvolání (zde odstranění vazby na straně central) spíše než na to, že klíč zůstane tajný.

11.13.5. Co šifrování zaručuje – a co ne

Spojení typu spárovat-a-zašifrovat poskytuje, v pořadí podle síly:

  • Důvěrnost. Vždy. Odposlouchávající nemůže bajty přečíst.

  • Integritu. Vždy. Pozměněné pakety neprojdou kontrolou autentizovaného šifrování na linkové vrstvě a jsou zahozeny.

  • Autentizaci. Pouze s mitm=True a schopným IO. Bez toho by se man-in-the-middle, který zachytil původní párovací výměnu, mohl vmísit; bez ochrany MITM nemají obě strany jak to zjistit.

Pro většinu případů použití kamery – telefon se s kamerou jednou spáruje a později se znovu připojí – obvykle stačí mitm=False, protože původní párování probíhá v kontrolovaném prostředí (uživatel drží obě zařízení ve stejné místnosti). Pro aplikace, kde spárované zařízení může kameru poprvé potkat na velkou vzdálenost nebo přes nedůvěryhodného prostředníka, je MITM správné nastavení.

11.13.6. Kdy je párování špatná odpověď

Párování má svou reálnou cenu: několik sekund výměny při prvním připojení, trvalé využití flash paměti pro každé vázané zařízení a scénář obnovy „zapomenout vazbu“, pokud se něco pokazí. Pro skutečně veřejná data – okolní senzorová měření publikovaná jako beacon, cedule zobrazující své jméno, cokoli, co se nezmění tím, že je přečteno nebo zapsáno – je správná odpověď nešifrovat vůbec a nechat jakýkoli nedaleký skener hodnoty číst.

Pro vše ostatní je connection.pair(bond=True) na straně central tím jednořádkovým doplňkem, který promění spojení z veřejného kanálu na soukromý.