Secure Storage est un ensemble de méthodes et de technologies pour protéger les données confidentielles sur un appareil : tokens, clés de chiffrement, informations de paiement et données personnelles des utilisateurs. Selon OWASP Mobile Top 10 (2024), le stockage non sécurisé des données fait partie des trois risques les plus critiques. Une implémentation appropriée de Secure Storage empêche la fuite de données même avec un accès physique à l'appareil.
Points clés
Secure Storage est la pratique de stockage des données confidentielles d'une application mobile de manière à les rendre inaccessibles aux autres applications, aux logiciels malveillants et aux attaquants ayant un accès physique à l'appareil. Contrairement au stockage classique, Secure Storage utilise le chiffrement, l'isolation et la protection matérielle.
Toutes les données n'ont pas besoin de Secure Storage : les images de profil ou le cache des actualités peuvent être stockés dans le système de fichiers classique. Cependant, les clés de chiffrement, les tokens d'authentification, les données de paiement, les clés privées et les modèles biométriques doivent être protégés. Selon Google Security Blog (2025), 67 % des vulnérabilités dans les applications mobiles sont liées au stockage des secrets en texte clair.
Chaque plateforme mobile fournit ses propres mécanismes Secure Storage : Android — Keystore et EncryptedSharedPreferences, iOS — Keychain et Data Protection API. Ces mécanismes sont intégrés aux modules de sécurité matérielle (TEE, Secure Enclave) et garantissent que les données ne peuvent pas être lues même après un jailbreak ou un root de l'appareil.
Le choix correct de la méthode Secure Storage dépend du type de données, du scénario d'utilisation et des exigences de performance. Comprendre l'architecture de chaque mécanisme permet au développeur de prendre la bonne décision architecturale.
La plateforme Android offre plusieurs niveaux de protection des données, du stockage matériel des clés aux SharedPreferences chiffrés. Le choix dépend de la sensibilité des données et des exigences de performance.
Android Keystore est un fournisseur cryptographique qui génère et stocke les clés dans un environnement d'exécution isolé (TEE — Trusted Execution Environment) sur les appareils prenant en charge la protection matérielle. Les clés ne quittent jamais le TEE : les opérations cryptographiques sont effectuées dans une zone protégée inaccessible même au système d'exploitation.
À partir d'Android 9 (API 28), Keystore prend en charge StrongBox Keymaster — une puce de sécurité dédiée avec son propre CPU, un générateur de nombres aléatoires matériel (TRNG) et une mémoire protégée. StrongBox est certifié conforme à Common Criteria EAL 4+ et constitue le plus haut niveau de sécurité de stockage de clés sur Android. Pour utiliser StrongBox, vous devez spécifier explicitement le drapeau inStrongBox() lors de la génération d'une clé.
Keystore prend en charge les algorithmes : AES/GCM/NoPadding (256 bits), EC (secp256r1, secp384r1), RSA (2048–4096 bits) et HMAC-SHA256. Toutes les clés peuvent être liées à l'authentification biométrique via setUserAuthenticationRequired(true).
EncryptedSharedPreferences est une bibliothèque du package AndroidX Security qui chiffre automatiquement toutes les données sauvegardées via l'API SharedPreferences. Les valeurs sont chiffrées avec une clé AES-256 GCM et les clés sont chiffrées avec AES-256 SIV (IV synthétique), empêchant les attaques par dictionnaire sur les noms de clés.
La clé de chiffrement principale est stockée dans Android Keystore, offrant une protection à deux niveaux : Keystore protège la clé maître, EncryptedSharedPreferences protège les données. Les performances de chiffrement sont inférieures à 5 ms par opération de lecture/écriture pour les données typiques (token, paramètres), ce qui rend la bibliothèque adaptée aux scénarios utilisateur.
EncryptedSharedPreferences n'est pas conçu pour les grands volumes de données (plus de 5 Mo) — pour ceux-ci, utilisez une base de données chiffrée via SQLCipher ou Room avec chiffrement.
SQLCipher est une extension de SQLite qui chiffre l'intégralité de la base de données page par page avec AES-256-CBC. Chaque page de la base de données est chiffrée avec une clé distincte dérivée du mot de passe maître via PBKDF2. SQLCipher ajoute environ 5–15 % de surcharge de performance selon la taille des données.
L'intégration avec Android se fait via la bibliothèque net.zetetic:android-database-sqlcipher, qui fournit une API compatible avec SQLiteOpenHelper standard. Il est recommandé de stocker le mot de passe SQLCipher dans Keystore, pas dans le code ou SharedPreferences.
La plateforme iOS fournit Keychain Services comme stockage sécurisé principal, ainsi que l'API Data Protection pour le chiffrement des fichiers au niveau du système d'exploitation.
Keychain est une base de données SQLite chiffrée où iOS stocke les mots de passe, les clés de chiffrement, les certificats et les notes. Chaque élément Keychain (SecItem) est stocké sous forme chiffrée à l'aide d'une clé matérielle unique à l'appareil. L'accès à un élément est contrôlé via une ACL (Access Control List), qui peut exiger une authentification biométrique (Face ID, Touch ID) ou un code d'accès.
Keychain prend en charge les classes de protection qui déterminent quand les données sont accessibles : kSecAttrAccessibleWhenUnlockedThisDeviceOnly — les données sont accessibles uniquement lorsque l'appareil est déverrouillé et ne sont pas transférées lors de la sauvegarde. Cette classe est recommandée pour la plupart des scénarios de stockage de tokens d'authentification.
Sur iOS 15+, le framework Security est disponible avec la prise en charge des clés matérielles via Secure Enclave — un processeur Apple dédié qui gère les opérations cryptographiques et stocke les clés privées dans une mémoire isolée. Secure Enclave prend en charge les algorithmes ECDSA (secp256r1) et ECDH pour générer des clés qui ne peuvent pas être extraites de la puce.
Data Protection est un mécanisme iOS qui chiffre chaque fichier au niveau du système de fichiers (APFS) à l'aide d'une clé liée au code d'accès de l'appareil. Le développeur spécifie le niveau de protection via l'attribut NSFileProtectionType lors de la création d'un fichier : NSFileProtectionComplete — le fichier est accessible uniquement lorsque l'appareil est déverrouillé.
Data Protection fonctionne automatiquement sur tous les appareils sous iOS 5+ si un code d'accès est défini. Le chiffrement est effectué au niveau matériel via le Dedicated AES Engine du processeur Apple, garantissant des performances élevées — la latence de chiffrement est pratiquement imperceptible pour l'utilisateur. Pour activer la protection dans une application, il suffit de définir l'attribut de protection lors de la création d'un fichier via FileManager.
Data Protection ne remplace pas Keychain pour le stockage des clés — il est utilisé pour chiffrer les fichiers, les bases de données Core Data et autres grands volumes de données. La combinaison de Keychain (pour les clés) et Data Protection (pour les fichiers) fournit un cycle complet de stockage sécurisé sur iOS.
Examinons des exemples pratiques de Secure Storage utilisant les API intégrées d'Android et iOS.
L'exemple montre l'initialisation d'EncryptedSharedPreferences avec une clé maître d'Android Keystore. Toutes les opérations ultérieures de lecture et d'écriture sont automatiquement chiffrées et déchiffrées.
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val prefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
prefs.edit()
.putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
.apply()
L'exemple illustre la sauvegarde et la lecture de données depuis iOS Keychain à l'aide du framework Security. Le code utilise kSecAttrAccessibleWhenUnlockedThisDeviceOnly pour une protection maximale.
import Security
func saveToKeychain(key: String, data: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
SecItemAdd(query as CFDictionary, nil)
}
func readFromKeychain(key: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(
query as CFDictionary, &result
)
return status == errSecSuccess ? result as? Data : nil
}
Un exemple de connexion à une base de données SQLite chiffrée via SQLCipher avec un mot de passe stocké dans Android Keystore.
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper
class SecureDBHelper(context: Context) :
SQLiteOpenHelper(context, "secure.db", null, 1) {
private val password = getKeyFromKeystore()
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
}
override fun onUpgrade(
db: SQLiteDatabase, oldVersion: Int, newVersion: Int
) {
onCreate(db)
}
}
// Utilisation : nous transmettons le mot de passe à l'ouverture
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)
L'utilisation appropriée de Secure Storage nécessite de suivre plusieurs principes fondamentaux qui préviennent les erreurs courantes des développeurs.
Définissez la classification des données : quelles données nécessitent une protection matérielle (Keystore / Secure Enclave), lesquelles nécessitent un chiffrement au niveau du système d'exploitation (EncryptedSharedPreferences / Data Protection), et lesquelles peuvent être stockées dans le système de fichiers classique. Les tokens d'authentification, les clés privées et les données de paiement — niveau matériel uniquement. Les paramètres utilisateur (thème, langue) — EncryptedSharedPreferences suffit. Les données de session (caches temporaires) peuvent être stockées en mémoire ou dans un répertoire temporaire.
Ne stockez jamais de secrets dans le code : les chaînes contenant des clés API, des mots de passe ou des phrases de récupération dans le code source sont une grave erreur de sécurité. Toute rétro-ingénierie exposera instantanément ces données. Utilisez Keystore pour les clés et, pour la configuration, un chargement côté serveur au démarrage de l'application (remote config).
Utilisez la liaison biométrique pour les opérations critiques : Android Keystore et iOS Keychain prennent en charge la liaison des clés à l'authentification biométrique. Chaque fois qu'une clé est accédée, le système demande Face ID, Touch ID ou la biométrie Android (BiometricPrompt). Cela garantit que même avec un contrôle total de l'appareil, un attaquant ne peut pas utiliser les données stockées sans le propriétaire.
Testez la sécurité : utilisez des outils d'analyse de sécurité — MobSF (Mobile Security Framework) pour l'analyse statique, objection pour les tests d'exécution et Frida pour contourner la protection. Vérifiez que les données sont inaccessibles après un root ou un jailbreak. Android permet de vérifier l'accès root via SafetyNet Attestation ou l'API Play Integrity, iOS — via la vérification d'intégrité de Secure Enclave.
Mettez régulièrement à jour les bibliothèques cryptographiques : les vulnérabilités dans les bibliothèques de chiffrement sont découvertes régulièrement. Surveillez les CVE pour AndroidX Security, SQLCipher et les wrappers Keychain. Implémentez un système de notification automatique des nouvelles versions via Dependabot ou Renovate.
Selon Apple Security Research (2025), une implémentation correcte de Secure Storage prévient 96 % des attaques visant le vol de données depuis l'appareil. Les 4 % restants sont des attaques avec accès physique et exploits zero-day, contre lesquelles la liaison biométrique est efficace.
Questions fréquentes
iOS Keychain est une base de données chiffrée pour stocker mots de passe, clés et certificats avec contrôle d'accès via ACL. Android Keystore est un fournisseur cryptographique qui génère et stocke les clés dans un environnement isolé (TEE/StrongBox) et ne permet pas d'extraire la clé privée.
EncryptedSharedPreferences utilise AES-256 GCM pour chiffrer les valeurs et AES-256 SIV pour chiffrer les clés. La clé maître est stockée dans Android Keystore, offrant une protection à deux niveaux. De plus, HMAC-SHA256 est utilisé pour la vérification d'intégrité.
Oui, HTTPS protège les données uniquement dans le canal de transmission. Sur l'appareil, les données sont stockées en texte clair après le déchiffrement. Si un attaquant obtient un accès physique à l'appareil ou installe un logiciel malveillant, HTTPS ne protégera pas les données stockées. Chiffrez toujours les données au niveau du stockage.
Utilisez Android Keystore avec le drapeau setUnlockedDeviceRequired(true), qui bloque l'accès aux clés sur les appareils rootés. Vérifiez également l'intégrité via l'API Play Integrity et si elle s'écarte des valeurs de référence, effacez tous les secrets du stockage.
Non, UserDefaults stocke les données en texte clair dans un fichier plist dans le sandbox. Toute application avec des outils de rétro-ingénierie (via une sauvegarde ou un jailbreak) peut lire les tokens. Seul Keychain est l'endroit sécurisé pour stocker les secrets sur iOS.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.