11.13. Сполучення і зв’язування¶
Все, що розглядалось до цього моменту, передає байти через радіоканал у відкритому вигляді. Будь-хто з BLE-сумісним ноутбуком у тій самій кімнаті може прослуховувати канали реклами, відстежувати послідовність перемикання каналів відкритого з’єднання та зчитувати кожне читання, запис і сповіщення, що проходять через нього. Для більшості публічних даних датчиків (рівень заряду батареї, температура навколишнього середовища) це прийнятно. Для всього, що обидві кінцеві точки хочуть зберегти в таємниці – регістру керування, що активує реле, пароля, вимірювання, яке не слід широко поширювати – канал зв’язку потребує шифрування, і в ідеалі камера повинна знати, з ким вона розмовляє.
BLE забезпечує обидва аспекти через сполучення і зв’язування.
11.13.1. Сполучення, зв’язування, шифрування¶
Три тісно пов’язані поняття:
Шифрування є кінцевою метою. Після шифрування каналу зв’язку кожен пакет у каналах даних може розшифрувати лише дві кінцеві точки; підслуховувач бачить лише шум.
Сполучення – це процедура, яку виконують дві кінцеві точки для узгодження ключів, що використовуються при шифруванні. Це одноразовий обмін, що генерує спільний ключовий матеріал, який рівень каналу зв’язку передає до свого модуля шифрування.
Зв’язування – це вибір зберегти ключі у енергонезалежній пам’яті після завершення сполучення, щоб наступне з’єднання між тими самими двома пристроями пропустило сполучення і перейшло безпосередньо до шифрування.
Простими словами: сполучення – це «познайомтеся»; зв’язування – це «запам’ятайте це знайомство»; шифрування – це «говоріть приватно з цього моменту».
Процес сполучення поверх відкритого BLE-з’єднання. Після завершення обміну ключами рівень каналу зв’язку шифрує кожен наступний пакет. Зв’язування – це додатковий крок запису ключів у флеш-пам’ять.¶
11.13.2. LE Secure Connections¶
Сучасний метод обміну ключами, що використовується BLE, – LE Secure Connections, побудований на основі еліптичних кривих Діффі-Геллмана. Обидві сторони генерують тимчасову пару ключів, обмінюються публічними половинами та комбінують результат зі своїми власними приватними ключами, отримуючи однаковий спільний секрет – секрет, який підслуховувач не може обчислити навіть маючи повний запис обміну.
Старіший метод LE Legacy є менш безпечним (підслуховувач з повним записом обміну зазвичай може відновити ключ) і існує лише для зворотної сумісності зі старими периферійними пристроями. За замовчуванням aioble використовує сучасний метод (le_secure=True); зберігайте його.
11.13.3. Ініціювання сполучення¶
Центральний пристрій виконує сполучення, викликаючи aioble.DeviceConnection.pair() на вже відкритому з’єднанні:
async with await device.connect() as connection:
await connection.pair(bond=True, le_secure=True, mitm=False)
# ... GATT work, now over an encrypted link ...
Після повернення з pair атрибути encrypted, authenticated, bonded та key_size з’єднання відображають результат переговорів.
Чотири найбільш корисних іменованих аргументи:
bond=True– зберегти отримані ключі у флеш-пам’ять, щоб наступне з’єднання між тими самими двома пристроями пропустило процедуру сполучення. За замовчуваннямTrue.le_secure=True– використовувати LE Secure Connections. За замовчуваннямTrue. Залишайте увімкненим.mitm=False– чи вимагати захисту від атак людина посередині. Для цього потрібен позасмуговий канал (числовий код, що відображається з одного боку і підтверджується з іншого, введений ключ доступу, …), щоб користувач міг перевірити, що два пристрої в процедурі сполучення – саме ті, що він очікує. За замовчуваннямFalse(без захисту від MITM – пасивний підслуховувач не може зчитати канал зв’язку, але зловмисник, що активно перенаправляє з’єднання, може здійснити сполучення від свого імені). ВстановлюйтеTrueдля будь-чого чутливого, але майте на увазі, що це вимагає від периферійного пристрою підтримки певної можливості вводу-виводу.io=3– можливість вводу-виводу, яку оголошує пристрій. Специфікація Bluetooth визначає п’ять:0лише дисплей,1дисплей + так/ні,2лише клавіатура,3немає вводу немає виводу,4клавіатура + дисплей. Камера без UI зазвичай оголошує3; якщо сама камера має дисплей, застосунок може відображати числове підтвердження і використовувати1. Комбінація можливостей вводу-виводу обох сторін визначає, чи досяжний реальний захист від MITM.
Периферійні пристрої не викликають pair самостійно – вони відповідають на те, що ініціює центральний пристрій. Чи вимагається шифрування для певної характеристики – це властивість того, як вона оголошена в базі даних GATT; біти доступу, що вимагають шифрування, є частиною низькорівневого API bluetooth і наразі не виставлені через конструктор характеристик aioble.
11.13.4. Зв’язування – і де зберігаються ключі¶
При bond=True aioble записує ключі у файл JSON у локальній файловій системі. Стандартне ім’я файлу – ble_secrets.json, що записується відносно поточного робочого каталогу. На свіжо завантаженій камері _boot.py вже вибрав цей каталог: /sdcard якщо карта підключена, /flash в іншому випадку – тому файл розміщується у /sdcard/ble_secrets.json або /flash/ble_secrets.json. Файл містить записи, необхідні для повторного шифрування каналу зв’язку наступного разу, коли зв’язаний вузол повторно підключиться, включаючи ідентифікаційну адресу вузла.
Одна асиметрія, яку слід пам’ятати: збереження відбувається автоматично при зміні ключів, але завантаження файлу при наступному завантаженні – ні. Викликайте aioble.security.load_secrets() один раз при запуску (до будь-якого сполучення або реклами), щоб раніше зв’язані вузли розпізнавались:
import aioble
aioble.security.load_secrets() # default path: ble_secrets.json
Після цього наступного разу, коли з’явиться зв’язаний вузол, aioble повторно використає збережені ключі і канал зв’язку зашифрується без додаткової процедури погодження.
Два практичних наслідки зберігання ключів у флеш-пам’яті:
Видалення пристрою. Видаліть
ble_secrets.json(або відповідний запис), щоб забути всіх зв’язаних вузлів, а потім виконайте сполучення з нуля.Фізичний доступ розкриває ключі. Будь-хто з доступом до файлової системи камери може прочитати JSON. Це та сама ситуація, що виникала на стороні мережі з ключами TLS (Операції: ключі, термін дії та усунення несправностей): використовуйте ключі для кожного пристрою окремо, вважайте будь-який збережений ключ відновлюваним і покладайтесь на можливість відкликання (тут – видалення зв’язку з боку центрального пристрою), а не на те, що ключ залишиться в таємниці.
11.13.5. Що гарантує шифрування – і що не гарантує¶
З’єднання з сполученням і наступним шифруванням забезпечує, в порядку від сильнішого до слабшого:
Конфіденційність. Завжди. Підслуховувач не може прочитати байти.
Цілісність. Завжди. Змінені пакети не проходять перевірку аутентифікованого шифрування на рівні каналу зв’язку і відкидаються.
Аутентифікація. Лише при
mitm=Trueі відповідній можливості вводу-виводу. Без цього зловмисник «людина посередині», що перехопив оригінальний обмін при сполученні, міг би вставити себе в ланцюжок; без захисту від MITM немає способу для обох сторін дізнатись про це.
Для більшості випадків використання камери – телефон, що одного разу сполучується з камерою, а потім повторно підключається – mitm=False зазвичай достатньо, оскільки початкове сполучення відбувається в контрольованому середовищі (користувач тримає обидва пристрої в одній кімнаті). Для застосунків, де сполучений пристрій може вперше зустріти камеру на великій відстані або через ненадійний посередник, MITM є правильним налаштуванням.
11.13.6. Коли сполучення – неправильна відповідь¶
Сполучення має реальну вартість: кілька секунд обміну при першому підключенні, постійне використання флеш-пам’яті для кожного зв’язаного пристрою, і процедура відновлення «забудьте зв’язок», якщо щось пішло не так. Для справді публічних даних – показань датчиків навколишнього середовища, опублікованих як маяк, вивіски, що відображає своє ім’я, всього, що не змінює стан системи при читанні або записі – правильна відповідь – не шифрувати взагалі, і дозволити будь-якому сканеру поблизу читати значення.
Для всього іншого connection.pair(bond=True) на центральному пристрої – це однорядкове доповнення, що перетворює канал зв’язку з публічного на приватний.