Bezdepbonusu7Программирование: статьи и ответы

Шифрование прошивки ESP32: пошаговая настройка

Архив Bezdepbonusu7Обновлено 5 мин чтения

Что изменилось в защите прошивки ESP32 к 2026 году

В статье используются esptool.py, ручной прожиг ключей через espefuse.py и смещения разделов PlatformIO. Принцип остался тем же, но инструменты и рекомендации Espressif обновились.

Актуальные версии

  • ESP-IDF 6.0 вышла в марте 2026 года, ветка поддерживается до сентября 2028. В ней по умолчанию используется Picolibc вместо Newlib, криптография переведена на PSA Crypto API, а часть устаревших драйверов удалена. Затем вышли исправления 6.0.x и минорная 6.1.
  • Для установки рекомендуется новый ESP-IDF Installation Manager (утилита eim).
  • esptool 5 перешёл на команды через дефис: esptool read-flash вместо esptool.py read_flash. Старые имена пока работают, но помечены устаревшими.

Что устарело в инструкции

  1. Ручная генерация и прожиг ключа нужны редко. Проще включить в menuconfig опцию Enable flash encryption on boot: при первом запуске загрузчик сам создаст ключ, запишет его в eFuse и зашифрует содержимое.
  2. Режим Development позволяет перепрошивать устройство по UART, Release блокирует такую запись. Для серийных изделий нужен только Release.
  3. Шифрование без Secure Boot v2 защищает от чтения, но не от подмены прошивки. Включайте обе функции вместе.
  4. Оригинальный ESP32 уязвим к атакам с внесением сбоев по питанию (CVE-2019-17391). Для новых проектов берите ревизию v3 или более новые чипы: ESP32-S3, C3, C6 используют XTS-AES и аппаратную защиту лучше.

Порядок действий сейчас

idf.py set-target esp32s3
idf.py menuconfig   # Security features
idf.py build flash monitor
espefuse summary    # проверка eFuse

Перед прожигом eFuse на партии устройств проверьте процесс на одной плате: операция необратима. Ведите учёт, какие ключи и биты защиты записаны, и учитывайте, что смещения разделов в PlatformIO зависят от выбранного фреймворка и таблицы разделов, поэтому значения из статьи переносить вслепую нельзя.

Шифрование прошивки ESP32

Смещение ПАМЯТИ по умолчанию в PlatformIO:

1. Загрузчик: 0x1000

2. Таблица разделов: 0x8000

3. Прошивка: 0x10000

Мы можем прочитать файл прошивки внутри комплекта esp32 с помощью следующей команды

esptool.py --port PORT --baud 230400 read_flash 0 0x40000 ./trick.bin

Файл прошивки хранится какrick.bin, и вы можете прочитать этот файл, используя любой из плагинов для чтения HEX в VScode.

Этапы шифрования

1. Клонируйте папку Esptool GitHub и выполните следующие команды

$ python setup.py install                 // To install from setup.py file
$ espefuse.py --port "COM12" Summary       //press the boot button now

Здесь он покажет карту внутренних предохранителей чипа. В основном мы можем сосредоточиться на следующих параметрах.

Внутренние предохранительные предохранители:

FLASH_CRYPT_CNT =0 , FLASH_CRYPT_CONFIG = 0

  • Флэш-ключ шифрования будет храниться в

BLOCK1 (BLOCK1): флэш-ключ шифрования

= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

  • Ключ шифрования безопасной загрузки будет храниться в

BLOCK2 (BLOCK2): безопасный ключ загрузки

2. Скомпилируйте исходный код и создайте файл "firmware.bin", используя любую платформу, например Arduino UNO или PlatformIO.

3. Сгенерируйте ключ флэш-шифрования для esp32

$ espsecure.py generate_flash_encryption_key "<path_to_bin_file_to_store_key>"

eg:
$ espsecure.py generate_flash_encryption_key flash_encryption_key.bin

Этот процесс необратим, делайте это только тогда, когда проект полностью настроен (в производстве)

4. Запишите ключ на свой esp32

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port PORT burn_key flash_encrytion "<path_to_bin_file_to_store_key>"

eg:
$ espefuse.py --port COM12 burn_key flash_encryption flash_encryption_key.bin

5. Теперь мы снова можем прочитать сводку и увидеть флеш-ключ шифрования

$ espefuse.py --port "COM12" Summary

Теперь блок 1 будет выглядеть примерно так

BLOCK1 (BLOCK1): флэш-ключ шифрования

= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-

6. Включение механизма флэш-шифрования

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port COM12 burn_efuse FLASH_CRYPT_CNT

7. Настройка флэш-шифрования для использования всех битов адреса вместе с ключом шифрования (максимальное значение 0x0F).

Нажмите кнопку загрузки и введите BURN

$ espefuse.py --port COM12 burn_efuse FLASH_CRYPT_CONFIG 0x0F

8. Теперь еще раз проверьте сводку эспефуза

$ espefuse.py --port "COM12" Summary

Теперь вы можете заглянуть внутрь предохранительных предохранителей -

FLASH_CRYPT_CNT = 1, FLASH_CRYPT_CONFIG = 15

9. Генерируем шифрование для раздела, загрузчика и прошивки

  • Шифрование таблицы разделов
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" --address 0x8000 --output path to store encrypted partition table.bin>" "<path to unencrypted partition.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x8000 --output partition_table_encrypted.bin build/partition_table/partition-table.bin

Эта команда шифрует двоичный файл таблицы разделов (partition-table.bin) с помощью ключа флэш-шифрования и выводит зашифрованную таблицу разделов в partition_table_encrypted.bin по адресу 0x8000.

  • Шифрование загрузчика
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" - address 0x1000 --output "<path to store encrypted bootloader.bin>" "<path to unencrypted bootloader.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x1000 --output bootloader_encrypted.bin build/bootloader/bootloader.bin

Эта команда шифрует двоичный файл загрузчика (bootloader.bin) с помощью ключа шифрования флэш-памяти, хранящегося в flash_encryption_key.bin. Затем зашифрованный загрузчик выводится на bootloader_encrypted.bin по адресу 0x1000.

  • Шифрование встроенного ПО:
$ espsecure.py encrypt_flash_data --keyfile "<path to key.bin>key.bin" --address 0x10000 --output "<path to store encrypted firmware.bin >" "<path to unencrypted firmware.bin>"

eg:
$ espsecure.py encrypt_flash_data --keyfile flash_encryption_key.bin --address 0x10000 --output firmware_encrypted.bin firmware.bin
  • Эта команда шифрует двоичный файл микропрограммы (firmware.bin) с помощью ключа шифрования флэш-памяти и выводит зашифрованную микропрограмму в firmware_encrypted.bin по адресу 0x10000.

Эти команды демонстрируют, как использовать espsecure.py для шифрования определенных разделов микропрограммы с помощью предоставленного ключа шифрования флэш-памяти. Полученные зашифрованные файлы затем можно прошить на устройство ESP32.

Перед выполнением этих команд убедитесь, что у вас есть необходимый ключ шифрования (flash_encryption_key.bin) и соответствующие двоичные файлы (bootloader.bin, partition-table.bin и firmware.bin) в указанных местах.

10. Наконец, запишите эти файлы на плату esp32, используя следующую команду, и нажмите кнопку загрузки.

$ python esptool.py --chip esp32 --port COM8 --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 "<path to encrypted bootloader.bin file>" 0x10000 "<path to encrypted firmware.bin file >" 0x8000 "<path to encrypted partition.bin file>"

eg:
$ esptool.py -p PORT -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader_encrypted.bin 0x8000 partition_table_encrypted.bin  0x10000 firmware_encrypted.bin

11. Проверьте, работает ли добавленный зашифрованный механизм, используя следующий код Arduino.

Сгенерируйте файл прошивки и убедитесь, что он закодирован ранее сгенерированным ключом

# include "esp_flash_encrypt.h"
void setup() {
  Serial.begin(115200);
}

void loop() {
  if (esp_flash_encryption_enabled())
    Serial.println("Encryption Enabled");
  else
    Serial.println("Encryption not Enabled");
}

→ Чтобы перепрограммировать плату, мы должны создать новый файл прошивки и зашифровать его с помощью существующего файла KEY.bin (flash_encryption_key.bin), а затем загрузить код в модель

→ Мы должны создать новый файл flash_encryption_key.bin для каждого модуля esp32.

Если после загрузки зашифрованного тестового кода вы получите этот вывод в последовательном терминале, поздравляем 👏👏👏, вы успешно включили механизм шифрования на своей плате esp32.

Обратите внимание на следующие параметры при создании файла загрузчика

Мы можем использовать ESP-IDF для создания файла bootloader.bin. Выполните следующие шаги для установки IDF. Используйте программу Hello_world для создания файла bootloader.bin и установите следующие параметры в меню-конфигурации.

  1. Установите уровень детализации журнала загрузчика (без вывода) - это уменьшит размер загрузчика, поэтому вы сможете включить флэш-шифрование без изменения смещения таблицы разделов в PlatformIO и в IDF.

2. Включить Flash Encryption (для тестирования процедуры установите режим использования только для разработки)

3. Дважды проверьте схему разделов и смещение таблицы разделов по адресу 0x8000.

Общие проблемы

Если вы получаете что-то вроде этой ошибки в последовательном терминале после загрузки нового кода, это означает, что вы не зашифровали прошивку с помощью ранее сгенерированного ключа.

Esp32SecurityEncryptionIoTProgramming

Похожие материалы

Статья из архива сайта: перевод и редактура материала сообщества разработчиков. Версии библиотек и инструментов могли измениться, сверяйтесь с официальной документацией.