安全
ESP8266 的固件是否能被读取?
ESP8266 固件放置在外部 flash,数据可被外部读取。并且 ESP8266 不支持 flash 加密,所有数据均为明文。
ESP8285 是否可以固件加密?
ESP8285 芯片自身未有固件加密功能,无法完成固件加密。
ESP32 及 ESP32-S2 芯片支持固件加密功能,用户可以考虑使用这两款芯片。
如仍需使用 ESP8285,用户可以选择外置加密芯片完成部分数据加密。
secure boot v1 和 secure boot v2 有什么区别?
secure boot v2 相较于 secure boot v1 主要做了以下方面的改进: - bootloader 和 app 使用相同的签名格式。 - bootloader 和 app 使用统一的签名密钥。
当前,仅 ESP32 v3.0 以下版本推荐使用 secure boot v1,ESP32 v3.0 及以上版本、ESP32-C3、ESP32-S2 和 ESP32-S3 推荐使用 secure boot v2。
开启 secure boot 后,为什么编译报错缺少文件?
错误日志:/Makefile.projbuild:7:/f/ESP32Root/secure_boot_signing_key.pem。
报错原因:security boot 是固件签名校验的功能,该功能需要生成密钥对。 - 启用 secure boot v1 时生成密钥对的方法请参考 secure boot v1 生成密钥。 - 启用 secure boot v2 时生成密钥对的方法请参考 secure boot v2 生成密钥。
模组使能 secure boot 后是否可以再次烧录?
若 secure boot v1 配置为 one-time,则仅支持烧录一次,不可以再重新烧录 bootloader 固件。
若 secure boot v1 配置为 reflashable,则可以重新烧录 bootloader 固件。
secure boot v2 允许重新烧录 bootloader 和 app 固件。
模组使能 flash encrypted,重新烧录后出现 flash read error
错误。如何解决?
模组开启加密功能后将不支持明文固件烧录,常见的错误请参考 重新烧录可能出现的错误。可以通过 espefuse 脚本关闭加密后再次烧录明文数据,或者参考 flash 加密示例,将加密后的固件数据烧录到设备上。
备注
flash encrypted 加密开关存在次数限制。
ESP32 打开 flash 加密和 secure boot 后,如何关闭?
如果您使用的是 one-time flash (Release) 模式,那么 flash 加密和 secure boot 都是不能关闭的。
如果您使用的是 reflashable (Development (NOT SECURE)) 模式,那么 flash 加密可以关闭,请参见 关闭 Flash 加密;secure boot 不能关闭。
ESP32 保护固件安全的方式有哪些?
ESP32 支持 flash 加密与 secure boot。
flash 加密参考文档:flash 加密。
安全引导参考文档:secure boot。
安全引导 V2 参考文档:v3.0 版本芯片的安全引导 V2。
ESP32 启动 flash 加密后进行 GDB 调试,为何会不断复位重启?
ESP32 启动了 flash 加密或 secure Boot 后,默认将会禁用 JTAG 调试,请参见 注意事项和补充内容。
可以通过 esptool 工具包中的
espefuse.py summary
脚本指令读取当前芯片 JTAG 状态。
ESP32 芯片如何开启 Flash 加密?
在 ESP-IDF 编译配置中,通过 menuconfig 或 idf.py menuconfig 中的
Security features
–>Enable flash encryption on boot (READ DOCS FIRST)
修改。请参见 Flash 加密说明。
ESP32 的 GPIO0 拉低后无法进入下载模式,日志打印 “download mode is disable” 是什么原因?
ESP32 芯片上电打印 “download mode is disable” 日志,说明该芯片的 UART 下载模式 (UART download mode) 已被禁用。您可以检查该芯片 eFuse 中的
UART_DOWNLOAD_DIS
位,查看该模式是否被禁用。注意,启用 flash 加密的量产模式后,UART 下载模式将默认被禁用。更多信息,请参考 UART ROM download mode。
在 Arduino 开发环境中使用 ESP32 能开启 secure boot 功能吗?
不能,如果要使用 Arduino 进行开发,开启 secure boot 功能的唯一方法是将 Arduino 作为 IDF 组件使用。
secure boot 和 flash 加密的使用场景有哪些?
启用 secure boot 后,设备将仅加载运行指定密钥签名后的固件。因此,启用 secure boot 可以避免设备加载非法的固件、防止对设备刷写未经授权的固件。
启用 flash 加密后,flash 上存储固件的分区以及被标识为 “encrypeted” 的分区中的数据将被加密。因此,启用 flash 加密可以避免 flash 上的数据被非法查看,并且从 flash 上拷贝的固件数据无法应用到其他设备上。
secure boot 和 flash 加密中涉及的存储在 eFuse 数据有哪些?
secure boot v1 中使用的存储在 eFuse 数据请参考 secure boot v1 efuses。
secure boot v2 中使用的存储在 eFuse 数据请参考 secure boot v2 efuses。
flash 加密中使用的存储在 eFuse 数据请参考 flash 加密 efuses。
启用 secure boot 失败,提示 “Checksum failure”,怎么解决?
启用 secure boot 后,bootloader.bin 的大小将增大,请检查引导加载程序分区的大小是否足够存放编译得到的 bootloader.bin。更多说明请参考 引导加载程序大小。
启用 NVS 加密失败,提示 nvs: Failed to read NVS security cfg: [0x1117] (ESP_ERR_NVS_CORRUPT_KEY_PART)
,怎么解决?
启用 NVS 加密前,建议先使用烧录工具擦除一次 flash,然后烧录包含使能 NVS 加密的固件。
启用 flash 加密后,提示 esp_image: image at 0x520000 has invalid magic byte (nothing flashed here)
,怎么解决?
启用 flash 加密后,将尝试对所有 app 类型的分区的数据进行加密,当 app 分区中没有存储对应的 app 固件时,将提示该 log。您可以在启用 flash 加密时对所有 app 类型的分区烧录预编译的 app 固件来避免出现这种警告。
使能 CONFIG_EFUSE_VIRTUAL
选项后,开启 flash 加密,为何相关数据未被加密?
Virtual eFuses 功能目前仅仅用于测试 eFuse 数据的更新,启用该功能后,flash 加密功能并未完全开启。
可以向一个未使能 flash 加密的设备中通过 OTA 更新一个使能了 flash 加密的 app 固件吗?
可以,请在编译时取消选中
Check Flash Encryption enabled on app startup
。
如何撤销 secure boot 的 key?
撤销 secure boot key 的操作是在
new_app.bin
固件中完成的。首先new_app.bin
必须附带两个签名。然后,下发new_app.bin
到设备上。最后,当旧的签名校验通过后,通过new_app.bin
中的esp_ota_revoke_secure_boot_public_key()
执行撤销旧 key 的操作。注意,如果您使用了 OTA 回滚方案,请在esp_ota_mark_app_valid_cancel_rollback()
返回ESP_OK
后再调用esp_ota_revoke_secure_boot_public_key()
。 更多说明请参考 Key Revocation。
启用 secure boot 或者 flash 加密(开发模式)后,无法烧录新固件,提示 Failed to enter Flash download mode
,怎么解决?
这种提示通常代表您使用的烧录命令不正确。请使用
idf.py
脚本执行idf.py bootloader
、idf.py app
命令编译bootloader.bin
、app.bin
。然后根据编译后的提示使用idf.py
执行烧录命令。如果还不能烧录程序,请使用espefuse.py -p PORT summary
命令查看当前设备的 eFuse,并检查flash download mode
是否是 enable 状态。
在配置了 ESP-IDF 环境的终端里输入 espefuse.py read_protect_efuse BLOCK3
指令对 Efuse BLOCK3 进行读保护后,再输入 esp_efuse_read_block()
读取 Efuse BLOCK3 的数据,数据全为 0x00,是什么原因?
Efuse BLOCK3 被读保护之后就不能再被读取了。
如何通过预烧录 eFuse 的方式使能 secure boot 或者 flash 加密?
默认情况下,可以通过向设备中烧录使能了 secure boot 或者 flash 加密的固件来启用 secure boot 或者 flash 加密。用户也可以通过下述两种通过预烧录 eFuse 的方式使能 secure boot 或者 flash 加密: - flash_download_tool 在使能 secure boot 或者 flash 加密时会自动预烧录 eFuse. - 通过使用 espsecure.py 和 espefuse.py 来生成密钥以及烧录对应的 eFuse 存储块。
启用 Secure Boot 后,使用 idf.py flash
命令无法烧录新的 bootloader.bin?
启用 Secure Boot 后,请使用
idf.py bootloader
命令编译新的 bootloader.bin。然后通过idf.py -p (PORT) bootloader-flash
命令烧录新的 bootloader.bin。在 ESP-IDF v5.2 及以上版本,你还可以通过使能
CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT
选项来解决该问题。关于该选项的说明,请参考 CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT。
启用 Secure Boot 或者 flash 加密后,如何查看设备中关于安全特性的信息?
请使用
esptool.py --no-stub get_security_info
命令查看设备的安全信息。
启用 Secure Boot 或者 flash 加密后,OTA 时应该注意什么?
启用 Secure Boot 后,你必须对 OTA 要使用的新固件进行签名,否则新固件无法被应用到设备上;
启用 flash 加密后,在生成新固件时,请保持使能 flash 加密的选项。
ESP32-S3 开启 flash 加密或 安全启动 后,会禁用哪些 USB 功能呢?
ESP32-S3 开启 flash 加密或安全启动后,会禁用 USB-JTAG 调试 功能,且不支持使用 USB 接口通过 idf.py dfu-flash 指令烧录固件的功能。
ESP32-S3 开启 flash 加密或安全启动后,支持 USB Host 和 USB Device 功能;支持使用 USB 接口通过
idf.py flash
指令下载固件的功能。
启用 flash 加密后,若设备的 eFuse 中存在多个用途为 XTS_AES_128_KEY
的 flash 加密密钥,设备将如何选择密钥?
设备将始终选择拥有最小的
Key ID
的密钥。
启用 Secure Boot V2 时,如何将用于校验签名的公钥存储到设备上?
公钥信息存储在设备的签名块中,当初次启用 Secure Boot V2 时,设备将自动从签名块中读取公钥信息并写入设备。
ESP 系列的产品开启 Secure Boot V2 功能后,是否还支持重烧固件?
ESP 系列的产品开启 Secure Boot V2 功能后,若没有禁用下载模式,则支持重烧固件。
注意:ESP 系列的芯片在开启 Secure Boot V2 功能后,Flash 下载工具的默认配置不支持重烧固件,需要修改 Flash 下载工具里的默认配置来支持重烧固件。以 ESP32-C3 为例:
修改 esp32c3 > security.conf 文件里的默认配置,将
flash_force_write_enable = False
改为flash_force_write_enable = True
。修改
esp32c3 > spi_download.conf
文件里的默认配置,将no_stub = False
改为no_stub = True
。若使用 esptool,则使用如下指令重烧固件:
esptool.py --chip esp32c3 -p COM68 -b 460800 --before=default_reset --after=no_reset --no-stub write_flash --force --flash_mode dio --flash_freq 80m --flash_size keep 0x0 bootloader.bin 0xF000 partition-table.bin 0x20000 blink.bin
flash 加密方案是否支持对文件系统的加密?
支持对 fatfs 文件系统执行加密,不支持对 spiffs 文件系统进行加密。
使用 NVS 加密时,如何制作加密的 nvs_data.bin
?
使能 NVS 加密方案时,设备不会在烧录的时候加密 NVS 数据,因此需要在 PC 端使用 脚本工具 来加密
nvs_data.bin
。使能 NVS 加密方案后,设备执行
nvs_set_*
类型的 API 时,会自动进行 NVS 数据的加密;执行nvs_get_*
类型的 API 时,会自动进行 NVS 数据的解密。
基于 ESP32 的 SPIFFS 文件系统是否支持使用 flash 加密方案进行加密?
不支持。SPIFFS 的内部结构不支持与 flash 加密方案的结合。如果需要一个支持 flash 加密的文件系统,可以考虑使用 FatFS 或 LittleFS 方案。
使用 ESP32-C3 基于 ESP-IDF v5.0.6 的 SDK,在软件配置中启用基于 flash 加密的 NVS 加密,设备在完成 flash 加密后重启固件,固件运行时报错如下,是什么原因?
I (438) main_task: Calling app_main() E (438) nvs: Failed to read NVS security cfg: [0x1117] (ESP_ERR_NVS_CORRUPT_KEY_PART) ESP_ERROR_CHECK failed: esp_err_t 0x1117 (ESP_ERR_NVS_CORRUPT_KEY_PART) at 0x42007e96 0x42007e96: app_main at /home/caiguanhong/esp/esp-idf-5.0.6/esp-idf/examples/wifi/getting_started/softAP/build/../main/softap_example_main.c:95 (discriminator 1) file: "../main/softap_example_main.c" line 95 func: app_main expression: ret abort() was called at PC 0x40386249 on core 0 0x40386249: _esp_error_check_failed at /home/caiguanhong/esp/esp-idf-5.0.6/esp-idf/components/esp_system/esp_err.c:47 Stack dump detected Core 0 register dump: MEPC : 0x40380938 RA : 0x40386254 SP : 0x3fc9a260 GP : 0x3fc91400 0x40380938: panic_abort at /home/caiguanhong/esp/esp-idf-5.0.6/esp-idf/components/esp_system/panic.c:425 0x40386254: __ubsan_include at /home/caiguanhong/esp/esp-idf-5.0.6/esp-idf/components/esp_system/ubsan.c:313
使用 基于 flash 加密的 NVS 加密方案 时,在启动应用程序前,必须彻底擦除 nvs_keys 分区。否则,应用程序可能会生成 ESP_ERR_NVS_CORRUPT_KEY_PART 错误代码。
在下载固件前,请先使用 idf.py erase-flash 指令擦除 flash。