Files
2026-10-11 01:27:15 +03:00

44 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Криптоподпись команды
> Источник: 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`).