11.13. Parkoppling och bindning¶
Allt som tagits upp fram till nu skickar bytes över radion i klartext. Vem som helst med en BLE-kapabel bärbar dator i samma rum kan lyssna på annonseringskanalerna, följa hoppsekvensen i en öppen anslutning och läsa av varje läsning, skrivning och avisering som passerar. För de flesta offentliga sensordata (batterinivå, omgivningstemperatur) är det helt i sin ordning. För allt som de två ändpunkterna vill hålla privat – ett styrregister som aktiverar ett relä, ett lösenord, en mätning som inte bör spridas brett – behöver länken vara krypterad, och helst behöver kameran veta vem den pratar med.
BLE tillhandahåller båda genom parkoppling och bindning.
11.13.1. Parkoppling, bindning, kryptering¶
Tre nära besläktade begrepp:
Kryptering är det slutgiltiga målet. När länken väl är krypterad kan varje paket på datakanalerna endast tydas av de två ändpunkterna; en avlyssnare ser brus.
Parkoppling är proceduren som de två ändpunkterna kör för att komma överens om de nycklar som krypteringen använder. Det är ett engångsutbyte som producerar delat nyckelmaterial som länklagret kopplar in i sin krypteringsmotor.
Bindning är valet att spara nycklarna till icke-flyktigt lagringsutrymme efter att parkopplingen slutförts, så att nästa anslutning mellan samma två enheter hoppar över parkopplingen och går direkt till kryptering.
På ren svenska: parkoppling är ”presentera er för varandra”; bindning är ”kom ihåg den här presentationen”; kryptering är ”prata privat från och med nu”.
Parkopplingsflödet ovanpå en öppen BLE-anslutning. När nyckelutbytet väl är klart krypterar länklagret varje efterföljande paket. Bindning är det extra steget att skriva nycklarna till flashminnet.¶
11.13.2. LE Secure Connections¶
Det moderna nyckelutbytet som BLE använder är LE Secure Connections, byggt på Elliptic Curve Diffie-Hellman. Båda sidor genererar ett tillfälligt nyckelpar, utbyter de publika halvorna och kombinerar resultatet med sina egna privata nycklar för att nå fram till samma delade hemlighet – en hemlighet som en avlyssnare inte kan beräkna ens med en fullständig registrering av utbytet.
Den äldre metoden LE Legacy är mindre säker (en avlyssnare med hela utbytet kan vanligtvis återskapa nyckeln) och finns endast för bakåtkompatibilitet med gammal kringutrustning. Standardvärdet i aioble är den moderna metoden (le_secure=True); behåll det.
11.13.3. Initiera parkoppling¶
En central parkopplar genom att anropa aioble.DeviceConnection.pair() på en redan öppen anslutning:
async with await device.connect() as connection:
await connection.pair(bond=True, le_secure=True, mitm=False)
# ... GATT work, now over an encrypted link ...
Efter att pair returnerat speglar attributen encrypted, authenticated, bonded och key_size på anslutningen det som förhandlades fram.
De fyra mest användbara nyckelordsargumenten:
bond=True– spara de resulterande nycklarna till flashminnet så att nästa anslutning mellan samma två enheter hoppar över parkopplingshandskakningen. StandardTrue.le_secure=True– använd LE Secure Connections. StandardTrue. Låt det vara på.mitm=False– huruvida man-in-the-middle-skydd ska krävas. Detta kräver en kanal utanför bandet (en numerisk kod som visas på ena sidan och bekräftas på den andra, en nyckelkod som skrivs in, …) så att användaren kan verifiera att de två enheterna i parkopplingshandskakningen faktiskt är de man tror. Standardvärdet ärFalse(inget MITM-skydd – en passiv avlyssnare kan inte läsa länken, men en angripare som aktivt omdirigerar anslutningar skulle kunna parkoppla sig in). Sätt tillTrueför allt känsligt, men var medveten om att det kräver att kringutrustningen faktiskt stöder en IO-förmåga.io=3– den IO-förmåga som enheten uppger. Bluetooth-specifikationen definierar fem:0endast skärm,1skärm + ja/nej,2endast tangentbord,3ingen inmatning ingen utmatning,4tangentbord + skärm. En kamera utan användargränssnitt rapporterar vanligtvis3; om kameran själv har en skärm kan applikationen visa den numeriska bekräftelsen och använda1. Kombinationen av de två sidornas IO-förmågor avgör om verkligt MITM-skydd är möjligt att uppnå.
Kringutrustning anropar inte pair själva – de svarar på vad centralenheten än initierar. Huruvida kryptering krävs för en given karakteristik är en egenskap hos hur den deklareras i GATT-databasen; åtkomstbitar för krypteringskrav är en del av det lågnivå-API:t bluetooth och exponeras för närvarande inte via konstruktorn för aioble-karakteristiken.
11.13.4. Bindning – och var nycklarna bor¶
När bond=True skriver aioble nycklarna till en JSON-fil på det lokala filsystemet. Standardfilnamnet är ble_secrets.json, skrivet relativt den aktuella arbetskatalogen. På en nyligen startad kamera har _boot.py redan valt den katalogen: /sdcard när ett kort är monterat, /flash annars – så filen hamnar på /sdcard/ble_secrets.json eller /flash/ble_secrets.json. Filen innehåller de poster som behövs för att återkryptera länken nästa gång den bundna motparten återansluter, inklusive motpartens identitetsadress.
En asymmetri att hålla i minnet: sparandet sker automatiskt allteftersom nycklar ändras, men inläsningen av filen vid nästa start gör det inte. Anropa aioble.security.load_secrets() en gång vid uppstart (innan någon parkoppling eller annonsering) så att tidigare bundna motparter känns igen:
import aioble
aioble.security.load_secrets() # default path: ble_secrets.json
Efter det, nästa gång en bunden motpart dyker upp, återanvänder aioble de lagrade nycklarna och länken blir krypterad utan någon ytterligare handskakning.
Två praktiska konsekvenser av att lagra nycklar på flashminnet:
Glömma bort en enhet. Radera
ble_secrets.json(eller ta bort den relevanta posten) för att glömma alla bundna motparter, parkoppla sedan om från grunden.Fysisk åtkomst läcker nycklar. Vem som helst med åtkomst till kamerans filsystem kan läsa JSON-filen. Detta är samma slags begränsning som dök upp på nätverkssidan med TLS-nycklar (Drift: nycklar, utgång och felsökning): använd nycklar per enhet, behandla varje lagrad nyckel som återvinningsbar och förlita dig på möjligheten att återkalla (här, att ta bort bindningen på centralsidan) snarare än på att nyckeln förblir hemlig.
11.13.5. Vad kryptering garanterar – och vad den inte gör¶
En länk som parkopplas-och-sedan-krypteras ger, i stigande styrka:
Konfidentialitet. Alltid. En avlyssnare kan inte läsa byten.
Integritet. Alltid. Modifierade paket misslyckas med länklagrets autentiserade krypteringskontroll och kastas.
Autentisering. Endast med
mitm=Trueoch en kapabel IO. Utan det kunde en man-in-the-middle som avlyssnat det ursprungliga parkopplingsutbytet ha infogat sig själv; utan MITM-skydd finns det inget sätt för de två sidorna att veta.
För de flesta kameraanvändningsfall – en telefon som parkopplar med kameran en gång och sedan ansluter igen senare – räcker mitm=False vanligtvis, eftersom den ursprungliga parkopplingen sker i en kontrollerad miljö (användaren håller båda enheterna i samma rum). För applikationer där en parkopplad enhet kan möta kameran för första gången över ett långt avstånd eller via en opålitlig mellanhand är MITM rätt inställning.
11.13.6. När parkoppling är fel svar¶
Parkoppling har en verklig kostnad: några sekunders utbyte vid första anslutningen, beständig flashanvändning för varje bunden enhet och återställningshistorien ”glöm bindningen” om något går fel. För genuint offentliga data – omgivningssensoravläsningar publicerade som en beacon, en skylt som visar sitt namn, allt som inte förändrar världen genom att läsas eller skrivas – är rätt svar att inte kryptera alls, och låta vilken närliggande skanner som helst läsa värdena.
För allt annat är connection.pair(bond=True) på centralenheten det enrads-tillägg som förvandlar länken från en offentlig kanal till en privat.