mirror of
https://github.com/anklimov/lighthub
synced 2026-10-28 11:15:00 +00:00
44 lines
6.5 KiB
Markdown
44 lines
6.5 KiB
Markdown
# Криптоподпись команды
|
||
|
||
> Источник: Wiki LightHub (lazyhome.ru), страница «криптоподпись\_команды». Снапшот от 2026-10-02.
|
||
|
||
В том случае, если надо гарантировать, что, даже получив доступ к локальной сети, MQTT брокеру или HTTP API, потенциальный злоумышленник не сможет выполнить критичную команду (например, открытие ворот), можно использовать механизм цифровой подписи команды.
|
||
|
||
Для задействования режима, необходимо пересобрать прошивку, добавив в приватный файл опций компиляции ([опции компиляции](https://www.lazyhome.ru/dokuwiki/doku.php?id=опции_компиляции)) (пример custom-build-flags/build\_flags\_lighthub21 для сборки под lighthub21) следующие опции (приведен пример):
|
||
|
||
```
|
||
-D CRYPT
|
||
-D PROTECTED_PINS=16,21
|
||
-D SHAREDSECRET=big_secret
|
||
```
|
||
|
||
### Как работает режим:
|
||
|
||
* Каждый контроллер, один раз в 30 секунд, передает в MQTT топик `<mqtt_root>/<controller_name>/$salt` случайное число, полученное с истинного датчика случайных чисел. Данное число (далее `<Salt>`) должно сохраняться авторизованной стороной и использоваться при создании цифровой подписи.
|
||
* Авторизованная сторона, желающая выполнить команду, вычисляет SHA256 хэш от строки, содержащей `<Salt><SHAREDSECRET><Команда>`
|
||
* при отправке MQTT команды, авторизованная сторона добавляет в MQTT Payload полученный хэш цифровой подписи ДО команды, отделив подпись от тела команды знаком @
|
||
* Контроллер, получив команду с подписью, производит аналогичную операцию по вычислению подписи и, если значения совпали, запрос считается авторизованным
|
||
* Если команда направлена на управление пином контроллера, из перечня PROTECTED\_PINS, заданного при компиляции прошивки, то она будет выполнена только том случае, если является авторизованной
|
||
|
||
### Ограничения
|
||
|
||
Если пин входит в перечень, заданный при компиляции в опции PROTECTED\_PINS, то для него действуют следующие ограничения, смысл которых в том, чтобы сделать крайне сложным подачу высокого логического уровня на выход контроллера (открытие мощных ключей) не имея физического доступа к самому устройству:
|
||
|
||
* Он не будет работать на канале типа термостат (THERMO)
|
||
* Для канала типа RELAY вывод работает только в не инверсном режиме. То есть, настройками не получится добиться перевода в состояние с высоким уровнем по-умолчанию, не получив подписанной команды. Настройки команды по умолчанию в файле конфигурации, также, будут проигнорированы. требуется цифровая подпись команде для управления таким каналом
|
||
|
||
* Восстановление значения канала при перезагрузке контроллера из статусных топиков MQTT не будет работать
|
||
* Форсуночный увлажнитель не будет инициализирован, если хотя бы один защищенный пин присутствует в его настройках (насос, клапана)
|
||
* Данные пины не работают для управления моторизированными воздушными заслонками (канал MOTOR)
|
||
* При использовании защищенных пинов в канале типа PWM требуется цифровая подпись команде для управления таким каналом
|
||
* Канал типа RELAYPWM на этом pin работать не будет
|
||
|
||
В качестве дополнительной меры защиты, рекомендуется отключить возможность обновления прошивки по-воздуху (OTA)
|
||
|
||
## Сверка с кодом (2026-10-02)
|
||
|
||
- Корректно: механизм реализован под флагом `CRYPT`: ключ `cryptoKey[] = QUOTE(SHAREDSECRET)` (`lighthub/main.cpp:110`), публикация `$salt` в топике устройства — `lighthub/main.cpp:2793-2804` (функция `publishStat()`, вызывается раз в 30 секунд из `thermoLoop()`, период `THERMOSTAT_CHECK_PERIOD=30000`, `lighthub/options.h:147`).
|
||
- Корректно: подпись вычисляется как SHA256 от `<Salt><SHAREDSECRET><Команда>` — `checkToken()` в `lighthub/utils.cpp:901-942` (sha256.update: saltStr, cryptoKey, data).
|
||
- Корректно: формат payload «подпись@команда» — разбор по символу `@` в `lighthub/item.cpp:752` (`char * authPos = strchr(payload,'@'); //token@command`).
|
||
- Корректно: ограничения для PROTECTED\_PINS подтверждены в коде: THERMO — `main.cpp:3237`; RELAY — `modules/out_relay.cpp:39,110`; MOTOR — `modules/out_motor.cpp:53,77,102`; PWM требует авторизованную команду — `modules/out_pwm.cpp:129-165`; SPRINKLER (увлажнитель) — `modules/out_sprinkler.cpp:50`. Перечень пинов задается опцией `PROTECTED_PINS` (`lighthub/options.h:390-403`).
|