Flash 加密
Flash 加密是 ESP32 系列芯片的重要安全特性,用于保护存储在外部 Flash 中固件和数据的机密性。启用 Flash 加密后,Flash 中的内容将被透明加密,防止通过物理方式读取获得明文固件和数据。
Flash 加密的核心特点:
透明加密解密:通过 MMU 缓存访问时自动处理加密解密
硬件实现:加密密钥存储在 eFuse 中,软件无法直接访问
XTS-AES 算法:采用专为存储设备设计的安全加密算法
分区选择性加密:可指定需要加密的分区类型
更多详细信息请参考:ESP-IDF Flash 加密文档
Flash 加密与安全启动
Flash 加密与安全启动是互补的安全功能:
Flash 加密:保护数据机密性,防止读取 Flash 内容
安全启动:保证代码完整性,防止运行未授权固件
建议在生产环境中同时启用两项功能以获得最佳安全保护。详情参考:Flash 加密与安全启动
加密范围
Flash 加密会自动加密以下内容:
二级引导加载程序
所有 app 类型分区
分区表
NVS 密钥分区
用户标记为 “encrypted” 的分区
重要提示:NVS 分区加密和 Flash 加密是两个独立的功能。需要使用 NVS 加密功能。详见:NVS 加密文档
加密范围详细说明:加密分区
Flash 加密功能支持列表
以下是 ESP32 系列芯片 Flash 加密功能对比表,包含加密算法、密钥长度/类型、硬件支持、密钥存储方式、密钥来源(精简描述):
芯片型号 |
支持的加密算法 |
密钥长度/类型 |
硬件加速/支持 |
密钥存储方式 |
密钥来源 |
---|---|---|---|---|---|
ESP32 |
AES-256(自定义实现) |
256-bit |
有 |
eFuse |
硬件随机数生成 |
ESP32-S2 |
XTS-AES-128、XTS-AES-256 |
256-bit 或 512-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
ESP32-S3 |
XTS-AES-128、XTS-AES-256 |
256-bit 或 512-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
ESP32-C2 |
XTS-AES-128 |
256-bit |
有 |
eFuse(BLOCK_KEY0) |
硬件随机数或主机生成 |
ESP32-C3 |
XTS-AES-128 |
256-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
ESP32-C5 |
XTS-AES-128 |
256-bit |
有 |
eFuse(BLOCK_KEYN)或Key Manager |
硬件随机数、主机生成或Key Manager |
ESP32-C6 |
XTS-AES-128 |
256-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
ESP32-H2 |
XTS-AES-128 |
256-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
ESP32-P4 |
XTS-AES-128、XTS-AES-256 |
256-bit 或 512-bit |
有 |
eFuse(BLOCK_KEYN) |
硬件随机数或主机生成 |
说明: - ESP32-C5 支持 Key Manager 作为密钥来源和存储方式(参考:ESP32-C5 SoC 功能宏定义)。 - 其它芯片均为 eFuse 存储,密钥可由硬件随机数生成或主机生成后烧录(参考:ESP32-S2 Flash 加密 和 ESP32-C3 Flash 加密)。
开发模式和发布模式
Flash 加密提供两种模式:
开发模式 (Development Mode)
允许多次烧录明文固件
引导加载程序自动处理加密
适用于开发和测试阶段
安全性相对较低
发布模式 (Release Mode)
禁用明文固件烧录
只能通过 OTA 更新明文固件
适用于生产环境
提供最高安全性
状态检查:
使用 esp_flash_encryption_enabled() 检查 Flash 加密状态
使用 esp_get_flash_encryption_mode() 获取加密模式(开发模式或发布模式)
配置方法详见:Flash 加密设置
加密过程
Flash 加密的基本过程:
首次启动:检测 eFuse 状态,启动加密流程
密钥生成:生成随机加密密钥并存储到 eFuse (可跳过,支持烧录自定义密钥)
就地加密:加密 Flash 中的指定分区内容
设置标志:标记 Flash 加密已启用
重启系统:开始正常的加密模式运行
完整的加密过程说明:Flash 的加密过程
应用程序访问加密分区
应用程序可以透明地访问加密的 Flash 内容:
读取加密 Flash:
使用 esp_partition_read() 或 esp_flash_read_encrypted() 读取明文内容(自动解密)
使用 esp_flash_read() 读取原始加密数据(不解密)
写入加密 Flash:
使用 esp_partition_write() 写入明文内容(自动加密)
使用 esp_flash_write_encrypted() 写入原始加密内容(跳过自动加密)
更多 API 详情:在加密的 Flash 中读写数据
重新烧录 Flash
开发模式下:
通过
idf.py encrypted-app-flash
烧录新的应用程序明文,烧录时会自动加密通过
idf.py encrypted-flash
烧录所有分区明文,烧录时会自动加密
发布模式下:
只能通过 OTA 更新明文固件
只能手动烧录密文固件(仅当 UART ROM Downloads 启用时支持)
详细说明:重新烧录更新后的分区
取消加密
仅开发模式支持:在加密状态下通过烧录 eFuse SPI_BOOT_CRYPT_CNT
以禁用 Flash 加密(发布模式无法取消)。
警告:每个芯片只有有限次数的开关加密次数,通常为 3 次(关闭->开启->关闭->开启),请谨慎操作。
详细步骤:关闭 Flash 加密
示例代码
完整的 Flash 加密使用示例请参考:
这些示例展示了:
Flash 加密状态检查
加密分区读写操作
NVS 和 FATFS 在加密环境下的使用
开发模式和发布模式的配置方法
最佳实践
生产环境使用发布模式
每个设备使用唯一密钥
结合安全启动使用
合理规划分区加密策略
测试 OTA 更新流程
更多最佳实践:Flash 加密最佳实践
常见问题 (FAQ)
请参考:ESP-FAQ 安全部分