Le chiffrement consiste à rendre les données illisibles pour toute personne ne possédant pas la clé de déchiffrement, assurant ainsi leur confidentialité.
Ce principe vous est sans doute familier grâce au petit cadenas affiché dans la barre d’adresse de votre navigateur : il indique que la communication entre votre appareil et le site web utilise le protocole sécurisé HTTPS. Ainsi, même si un attaquant intercepte le trafic, il ne pourra pas en lire le contenu.
Toutefois, la protection des données ne se limite pas aux échanges réseau. Dans le cas des objets connectés, il est tout aussi crucial de chiffrer la mémoire Flash, afin d’empêcher l’accès ou la modification non autorisés des informations stockées localement.
Pourquoi chiffrer la mémoire Flash d’un objet connecté IoT ?
Le “cerveau” d’un objet connecté IoT (Internet of Things) est un micro-contrôleur, qui stocke ses données persistantes (programme, configuration Wi-Fi…) dans une mémoire Flash. Ce type de mémoire conserve en effet les données même sans alimentation.
Une personne ayant un accès physique à un objet connecté peut dès lors lire le contenu de cette mémoire et en extraire des secrets, informations cruciales pour la sécurité de votre réseau (certificats de sécurité, mot de passe de l’application, mots de passe Wi-Fi…). Il est donc indispensable de chiffrer cette mémoire afin de rendre ces secrets illisibles pour un attaquant. Il existe d’ailleurs maintenant des puces spécialisées pour le stockage des secrets (ex : TPM).
La plupart des objets connectés “grand public”, comme les capteurs de température ou les caméras de vidéo-surveillance, ne sont pas équipés de puce TPM et leur mémoire Flash est rarement chiffrée. Or ces objets sont généralement connectés à un réseaux Wi-Fi.
Les communications sur les réseaux Wi-Fi sont maintenant relativement sécurisés avec une clé de chiffrement WPA2-PSK. Mais un attaquant qui a un accès physique à un objet connecté (un capteur dans une usine, une caméra dans votre jardin), peut facilement extraire cette clé de la mémoire Flash non chiffrée de cet objet.
Voici un exemple minimaliste de code pour un objet connecté basé sur un microcontrôleur ESP32, qui se connecte au réseau Wi-Fi TP-Link_21B7 (SSID) avec le mot de passe R3seauS3cur1t3IoT! :
// Example used to show how Wi-Fi password
// can be extracted from Flash memory
//
// https://tutoduino.fr/
#include <WiFi.h>
const char *ssid = "TP-Link_21B7";
const char *passphrase = "R3seauS3cur1t3IoT!";
void setup() {
Serial.begin(115200);
delay(100);
WiFi.begin(ssid, passphrase);
Serial.println();
Serial.println();
Serial.print("Waiting for WiFi... ");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
delay(1000);
}Le nom du réseau Wi-Fi (ssid) et son mot de passe (passphrase) sont des constantes qui vont être stockées dans la mémoire Flash du microcontrôleur.
Après avoir connecté l’objet via son port USB à un ordinateur sous Linux, il est trivial d’extraire les identifiants Wi-Fi de sa mémoire Flash :

Voici cet exemple illustré en vidéo :
Comment chiffrer la mémoire Flash sur un ESP32 ?
Le framework ESP-IDF permet de chiffrer la mémoire flash des ESP32 avec une procédure relativement simple.
Voici les principales étapes :
#1. Générer une clé de chiffrement
Vous pouvez utiliser la clé de chiffrement matérielle intégrée à l’ESP32 (unique pour chaque puce) ou générer votre propre clé de chiffrement personnalisée. Chaque méthode présente ses avantages et ses inconvénients. Dans ce tutoriel, à des fins pédagogiques, j’ai choisi de générer ma propre clé de chiffrement.
Voici comment générer votre propre clé de chiffrement :
espsecure.py generate_flash_encryption_key my_key.binCette clé a une taille de 256 bits, qui permettra de chiffrer avec un bon niveau de sécurité vos firmwares. Attention cette clé sera nécessaire pour toute les futures modifications de firmware de votre objet connecté, elle doit être conservée précieusement.
#2. Brûlez-la clé de chiffrement dans un eFuse du micro-contrôleur
Votre clé de chiffrement doit être écrite dans l’ESP32. Afin de garantir la confidentialité absolue de la clé et d’empêcher toute lecture ou modification ultérieure, le dispositif utilise le mécanisme de programmation eFuse.
Un eFuse (fusible électronique) est un composant matériel intégré directement dans la puce de l’ESP32. Contrairement à la mémoire flash standard, c’est une mémoire OTP (One-Time Programmable) : une fois un bit activé, il ne peut plus être modifié ni effacé. Cette opération est donc permanente et irréversible.
espefuse --port /dev/ttyUSB0 burn_key flash_encryption my_key.binVoici le résultat de cette commande si tout se déroule bien :
steph@F15:~/esp/esp-idf-5.5.1$ espefuse --port /dev/ttyUSB0 burn_key flash_encryption my_key.bin
espefuse v4.11.dev2
Connecting.....
Detecting chip type... ESP32
=== Run "burn_key" command ===
Sensitive data will be hidden (see --show-sensitive-info)
Burn keys to blocks:
- BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
Reversing the byte order
Disabling read to key block
Disabling write to key block
Burn keys in efuse blocks.
The key block will be read and write protected (no further changes or readback)
Check all blocks for burn...
idx, BLOCK_NAME, Conclusion
[00] BLOCK0 is not empty
(written ): 0x0000000400000000000014380000b00000a5840d8e19b63400000000
(to write): 0x00000000000000000000000000000000000000000000000000010080
(coding scheme = NONE)
[01] BLOCK1 is empty, will burn the new value
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BURN BLOCK1 - OK (write block == read block)
BURN BLOCK0 - OK (all write block bits are set)
Reading updated efuses...
Successful
Votre clé de chiffrement de 256 bits est stockée dans le BLOCK1 des fusibles, elle est protégée en lecture/écriture.
Nous pouvons vérifier par la suite que nous n’avons aucun accès en lecture à la clé de chiffrement :
espefuse --port /dev/ttyUSB0 summaryRenvoie des points d’interrogation pour BLOCK1, la clé de chiffrement est correctement protégée en lecture.
BLOCK1 (BLOCK1) Flash encryption key
= ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
#3. Activer le chiffrement de la flash dans le micro-contrôleur (attention, ceci est irréversible)
Deux eFuse spécifiques doivent être brûlés pour activer le chiffrement de la flash :
- FLASH_CRYPT_CNT : Compteur qui limite le nombre de tentatives pour activer le chiffrement, empêchant toute réinitialisation non autorisée du chiffrement. Sa valeur doit être impair pour activer le chiffrement.
- FLASH_CRYPT_CONFIG : Définit les paramètres du chiffrement. La valeur 0x0F active le chiffrement AES-256 pour toutes les données stockées dans la mémoire Flash (y compris le bootloader, l’application et les données utilisateur).
espefuse --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CNT 1
espefuse --port /dev/ttyUSB0 burn_efuse FLASH_CRYPT_CONFIG 0x0FVérifions les valeurs des fusibles électroniques à cette étape :
espefuse --port /dev/ttyUSB0 summaryFLASH_CRYPT_CNT est défini sur 1 et FLASH_CRYPT_CONFIG est défini sur 0xf, cela semble correct.
Flash fuses:
FLASH_CRYPT_CNT (BLOCK0) Flash encryption is enabled if this field has an o = 1 R/W (0b0000001)
dd number of bits set
FLASH_CRYPT_CONFIG (BLOCK0) Flash encryption config (key tweak bits) = 15 R/W (0xf)
#4. Activer le chiffrement de la partition NVS
La partition NVS (Non-Volatile Storage) est une partition spéciale de la flash. Son rôle principal est de stocker des données de configuration persistantes qui doivent survivre à un redémarrage ou à une coupure d’alimentation. La partition NVS doit être chiffrée afin de protéger les données sensibles comme les mots de passe.
Le chiffrement de la partition NVS se fait de la manière suivante dans l’IDE Arduino :
- Sélectionner le schéma de partition “Custom“
- Créer le fichier “partitions.csv” dans le répertoire où est stocké votre croquis sur votre ordinateur
- Configurer le schéma de partition souhaité au format csv dans ce fichier
- Ajouter le flag “encrypted” pour la partition NVS
- Compiler le programme dans l’IDE Arduino (il peut être utile de supprimer auparavant le répertoire cache arduino)

#5. Chiffrer le firmware
Après avoir compilé le programme sous l’IDE Arduino, il faut exporter les fichiers binaires générés.

Cela positionne tous les fichiers nécessaires dans le sous-répertoire build du répertoire où est stocké votre croquis Arduino.
Le fichier flash_args contient le nom des fichiers qu’il va falloir chiffrer et à quel offset il va falloir ensuite les flasher dans la mémoire de l’ESP32 :

Chiffrer tous ces fichiers binaires avec votre clé de chiffrement en indiquant en paramètre leur adresse dans la mémoire Flash.
$ espsecure encrypt_flash_data \
--keyfile my_key.bin \
--address 0x1000 \
--output bootloader_enc.bin \
bootloader.bin
$ espsecure encrypt_flash_data \
--keyfile my_key.bin \
--address 0x8000 \
--output partitions_enc.bin \
partitions.bin
$ espsecure encrypt_flash_data \
--keyfile my_key.bin \
--address 0xe000 \
--output boot_app0_enc.bin \
boot_app0.bin
$ espsecure encrypt_flash_data \
--keyfile my_key.bin \
--address 0x10000 \
--output firmware_enc.bin \
firmware.bin #6. Flasher le firmware chiffré dans la mémoire Flash de l’ESP32
Flasher tous les binaires chiffrés à l’étape précédente dans la mémoire flash de l’ESP32 :
esptool --chip esp32 --port /dev/ttyUSB0 \
write_flash \
0x1000 bootloader_enc.bin \
0x8000 partitions_enc.bin \
0xe000 boot_app0_enc.bin \
0x10000 firmware_enc.binLe chiffrement assure la confidentialité des données !
En répétant la procédure du début de ce tutoriel, il devient impossible d’extraire les données en clair de la mémoire Flash.

Le firmware est également chiffré, il n’est plus possible de réaliser d’ingénierie inverse dessus :

Conclusion
Le chiffrement de la mémoire Flash assure la confidentialité des données qu’elle stocke et apporte de nombreux bénéfices aux niveau de la cybersécurité de votre objet connecté IoT :
✅ Bootloader chiffré
- Empêche l’exécution de code malveillant au démarrage.
- Protège contre les attaques par modification du bootloader (ex. : injection de malware).
- Garantit l’intégrité du processus de démarrage.
✅ Application protégée
- Rend le code illisible sans la clé de chiffrement.
- Empêche l’ingénierie inverse (reverse engineering) pour voler la propriété intellectuelle.
- Sécurise les algorithmes sensibles (ex. : protocoles de communication, logiques métiers).
✅ Mot de passe Wi-Fi inextractible
- Empêche la récupération du mot de passe même avec un accès physique à la mémoire.
- Réduit les risques de piratage du réseau via l’extraction des identifiants.
- Protège la confidentialité des données transmises sur le réseau.
✅ Clone du firmware impossible sans la clé de chiffrement
- Empêche la duplication non autorisée du firmware (protection contre la contrefaçon).
- Garantit l’authenticité du matériel (seuls les appareils légitimes peuvent fonctionner).
- Protège les revenus et la réputation en évitant les copies illégales.
En résumé : Le chiffrement de la mémoire Flash renforce la sécurité, protège la propriété intellectuelle et limite les risques de piratage ou de contrefaçon. Un must pour les appareils connectés ! 🔒
