Android Keystore est un fournisseur cryptographique qui génère et stocke les clés de chiffrement dans un environnement d’exécution isolé (TEE), inaccessible même au système d’exploitation. Selon AOSP Security Documentation (2025), Keystore est utilisé dans plus de 80 % des applications Android du top 100 de Google Play pour protéger les jetons et chiffrer les données. Comprendre Android Keystore est essentiel pour le stockage sécurisé des clés sur Android.
À retenir
Android Keystore — un composant système de la plateforme Android qui fournit une API pour générer, stocker et utiliser des clés cryptographiques dans un environnement protégé. Contrairement aux bibliothèques cryptographiques logicielles (Bouncy Castle, Conscrypt), Keystore garantit que les clés privées ne quittent jamais la zone d’exécution isolée.
Keystore est apparu pour la première fois dans Android 4.3 (API 18) en tant que fournisseur logiciel avec prise en charge RSA. À partir d’Android 6.0 (API 23), Keystore a bénéficié d’un support matériel via Keymaster Hardware Abstraction Layer (HAL), qui délègue les opérations cryptographiques à Trusted Execution Environment (TEE) sur les appareils compatibles. Selon le Android Compatibility Definition Document (2025), tous les appareils avec Android 9+ doivent prendre en charge Keystore matériel via TEE ou StrongBox.
Les clés dans Keystore sont identifiées par un alias — une chaîne transmise lors de la création ou du chargement d’une clé. Keystore ne permet pas d’accéder au matériel brut de la clé : les méthodes getEncoded() retournent null pour les clés créées dans Keystore. Ceci est une différence fondamentale avec les clés logicielles — un attaquant ne peut pas extraire la clé privée même avec un contrôle total de l’appareil.
Keystore est intégré à d’autres mécanismes de sécurité Android : authentification biométrique (BiometricPrompt), chiffrement au niveau des fichiers (File-Based Encryption) et fonctions de vérification SafetyNet / Play Integrity. Les clés peuvent être configurées pour une suppression automatique sous certaines conditions : lors de la suppression du code d’accès, de l’ajout d’une nouvelle empreinte digitale ou à l’expiration.
L’architecture Android Keystore comprend trois niveaux d’implémentation qui diffèrent par le degré de protection matérielle. Le niveau dépend des capacités matérielles de l’appareil.
TEE (Trusted Execution Environment) — une zone isolée fonctionnant en parallèle du système d’exploitation principal sur le même processeur. TEE utilise la technologie ARM TrustZone, qui divise le cœur physique du processeur en deux virtuels : Normal World (Android) et Secure World (TEE). Le code dans Secure World a accès à la mémoire et aux périphériques inaccessibles depuis Normal World.
Lorsqu’une application appelle une opération cryptographique via Keystore, la demande est transmise via Keymaster HAL à TEE, où l’opération est effectuée par le matériel. Le résultat est renvoyé à l’application, mais la clé privée reste dans la mémoire protégée de TEE. TEE est certifié conforme au GlobalPlatform TEE Protection Profile et est une exigence obligatoire pour Android 9+ sur les appareils avec des processeurs prenant en charge TrustZone.
TEE prend en charge les algorithmes AES/GCM (128, 256 bits), RSA (2048, 4096 bits), EC (P-256, P-384, P-521) et HMAC-SHA256. Les performances de TEE sont inférieures à celles de la cryptographie logicielle (de 20 à 40 %), mais pour les opérations typiques (signature JWT, déchiffrement de clé de session), la latence ne dépasse pas 10–50 ms.
StrongBox — une puce de sécurité dédiée, physiquement séparée du processeur principal. Contrairement à TEE, qui partage le temps processeur avec Android, StrongBox possède son propre CPU, sa RAM, un générateur de nombres aléatoires véritable (TRNG) et un stockage sécurisé (mémoire programmable une seule fois). StrongBox est certifié Common Criteria EAL 4+ et Secure IC Protection Profile.
StrongBox est disponible sur les appareils avec Android 9+ à condition que la puce correspondante soit présente (par exemple, Titan M sur Google Pixel, Knox sur Samsung Galaxy). Le développeur active StrongBox via le flag setIsStrongBoxBacked(true) dans KeyGenParameterSpec. Si le support matériel n’est pas disponible, le flag est ignoré et Keystore revient à TEE.
Limitations de StrongBox : prend en charge un ensemble limité d’algorithmes (AES-256, EC P-256, HMAC-SHA256), file d’opérations — pas plus d’une à la fois, nombre d’opérations — limité par les ressources de la puce. StrongBox n’est pas conçu pour les scénarios à forte charge — utilisez TEE pour les opérations fréquentes et StrongBox uniquement pour les clés critiques (clés de chiffrement maîtres, clés de signature).
Le Keystore logiciel est une implémentation logicielle utilisée sur les appareils sans support matériel pour TEE ou StrongBox. Les clés sont stockées chiffrées dans le système de fichiers, mais la clé privée peut être temporairement déchiffrée dans la RAM. Keystore logiciel est moins sécurisé — un attaquant avec accès root peut intercepter la clé en mémoire.
À partir d’Android 12 (API 31), Google exige un Keystore matériel pour tous les nouveaux appareils. Les appareils avec Android 9–11 peuvent avoir un Keystore logiciel sur les modèles d’entrée de gamme. Le développeur peut vérifier le niveau de protection via KeyStore.getKeyCharacteristics() — l’attribut SECURITY_LEVEL_TRUSTED_ENVIRONMENT ou SECURITY_LEVEL_STRONGBOX confirme la protection matérielle.
Android Keystore prend en charge une large gamme d’algorithmes cryptographiques, divisés en catégories selon le type de clé. Le choix de l’algorithme affecte les performances, la compatibilité et le niveau de sécurité.
AES (Advanced Encryption Standard) — chiffrement symétrique pour protéger les données sur l’appareil. Mode recommandé : AES/GCM/NoPadding (256 bits). GCM fournit un chiffrement authentifié (AEAD) — vérification d’intégrité des données chiffrées. Taille IV (vecteur d’initialisation) : 12 octets pour GCM. N’utilisez pas AES/ECB — il n’offre pas une protection adéquate.
RSA (Rivest–Shamir–Adleman) — chiffrement asymétrique pour protéger les clés de session et les signatures numériques. Taille recommandée : 2048 ou 4096 bits. Modes : RSA/ECB/PKCS1Padding (chiffrement) et RSA/ECB/PKCS1Sign (signature). RSA 1024 est considéré comme obsolète et n’est pas recommandé pour les nouvelles applications (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — cryptographie asymétrique sur courbes elliptiques pour la signature et l’échange de clés. Courbes prises en charge : secp256r1 (P-256, obligatoire), secp384r1 (P-384) et secp521r1 (P-521). EC offre une sécurité comparable à RSA avec une taille de clé considérablement plus petite. P-256 est recommandé pour la plupart des scénarios : il est pris en charge par tous les appareils et offre un niveau de sécurité de 128 bits.
HMAC (Hash-based Message Authentication Code) — authentification symétrique de messages. Fonctions de hachage prises en charge : SHA-256, SHA-384, SHA-512. HMAC est utilisé pour vérifier l’intégrité et l’authenticité des données, par exemple pour vérifier les requêtes webhook ou l’intégrité de la configuration.
Tous les algorithmes peuvent être liés à l’authentification biométrique via KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). Sur Android 11+, le flag setUserAuthenticationParameters() est disponible avec un délai d’expiration (en secondes) pendant lequel la clé est disponible après l’authentification biométrique, sans demande répétée.
Penchons-nous sur des exemples pratiques de travail avec Android Keystore en Kotlin : générer une clé AES, chiffrer des données et créer une paire asymétrique pour la signature.
L’exemple crée une clé AES/GCM de 256 bits avec liaison à l’authentification biométrique. La clé ne peut pas être exportée via getEncoded().
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
fun generateAesKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setKeySize(256)
.setBlockModes(KeyProperties.KEY_BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
val generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore"
)
generator.init(spec)
generator.generateKey()
}
L’exemple chiffre des données en utilisant une clé d’Android Keystore. Cipher obtient la clé par alias, initialise le chiffrement AES/GCM et retourne les données chiffrées avec l’IV.
fun encryptData(alias: String, plaintext: ByteArray): ByteArray {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val iv = cipher.getIV()
val encrypted = cipher.doFinal(plaintext)
// IV + données chiffrées
return iv + encrypted
}
fun decryptData(alias: String, ciphertextWithIv: ByteArray): ByteArray {
val iv = ciphertextWithIv.copyOfRange(0, 12)
val encrypted = ciphertextWithIv.copyOfRange(12, ciphertextWithIv.size)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
val spec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec)
return cipher.doFinal(encrypted)
}
L’exemple crée une paire de clés RSA-2048 dans Keystore avec liaison StrongBox. La clé privée est utilisée pour signer, la clé publique peut être exportée via getEncoded().
fun generateRsaKeyPair(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_SIGN or
KeyProperties.PURPOSE_VERIFY
)
.setKeySize(2048)
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setIsStrongBoxBacked(true)
.build()
val pair = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
).apply { init(spec) }
.generateKeyPair()
// La clé publique peut être exportée
val publicKey = pair.public // X509EncodedKeySpec
}
L’utilisation efficace d’Android Keystore nécessite le respect de règles qui garantissent une protection maximale tout en maintenant les performances.
Utilisez KeyGenParameterSpec avec les paramètres minimalement nécessaires : spécifiez uniquement les purpose, modes de bloc et paddings réellement utilisés. Les paramètres redondants (par exemple, PURPOSE_ENCRYPT pour une clé utilisée uniquement pour la signature) créent des vecteurs d’attaque inutiles. Android recommande de spécifier explicitement le digest pour la signature — SHA256 est le niveau minimal acceptable (SHA1 est obsolète).
Liezez les clés à la biométrie pour les opérations critiques : setUserAuthenticationRequired(true) garantit que la clé ne peut être utilisée qu’après authentification biométrique. Sur Android 11+, utilisez setUserAuthenticationParameters() avec un délai (recommandé 30–60 secondes) pour éviter de demander la biométrie pour chaque opération dans une même session. setInvalidatedByBiometricEnrollment(true) supprime automatiquement la clé lors de l’ajout d’une nouvelle empreinte ou d’un nouveau visage — cela empêche l’accès avec d’anciennes données biométriques.
Vérifiez le niveau de sécurité lors de l’initialisation : utilisez KeyStore.getKeyCharacteristics() pour déterminer SECURITY_LEVEL. Si l’appareil ne prend en charge que le Keystore logiciel (SECURITY_LEVEL_SOFTWARE), prenez une décision : soit refuser la fonctionnalité, soit utiliser un chiffrement supplémentaire (par exemple, enveloppement de clé via mot de passe utilisateur). Ne vous fiez pas à StrongBox s’il n’est pas garanti — spécifiez toujours le flag setIsStrongBoxBacked(true) et vérifiez le résultat via getKeyCharacteristics.
Effectuez une rotation des clés régulièrement : les clés cryptographiques ont une durée de vie recommandée. NIST SP 800-57 recommande de changer les clés AES tous les 1–2 ans, les paires RSA/EC tous les 2–3 ans. Implémentez un mécanisme de rotation des clés : vérifiez la date de création de la clé au démarrage de l’application (KeyGenParameterSpec.Builder.setKeyValidityStart/End) et générez une nouvelle clé à l’expiration. Les anciennes données chiffrées avec l’ancienne clé doivent être déchiffrées et rechiffrées avec la nouvelle.
N’utilisez pas Keystore pour les grandes données : Keystore est conçu pour stocker des clés (quelques centaines d’octets), pas pour chiffrer de gros fichiers. Pour le chiffrement des données, utilisez le schéma : générez une clé AES aléatoire (DEK — Data Encryption Key), chiffrez les données avec cette clé, et chiffrez le DEK avec une clé Keystore (KEK — Key Encryption Key). Android EncryptedSharedPreferences utilise exactement ce schéma : clé maître dans Keystore, données — AES-256 GCM.
Foire aux questions
Non, Android Keystore est conçu pour que la clé privée ne quitte jamais TEE ou StrongBox. La méthode getEncoded() retourne null pour les clés créées dans Keystore. La clé ne peut être utilisée que via Cipher, Signature ou Mac API — le matériel brut est inaccessible.
TEE (TrustZone) — isolation virtuelle sur le même processeur, utilise le partage de temps. StrongBox — une puce séparée avec son propre CPU et sa mémoire. StrongBox est plus sécurisé (Common Criteria EAL 4+), mais plus lent et prend en charge moins d’algorithmes. TEE convient aux opérations fréquentes, StrongBox aux clés critiques.
Utilisez KeyStore.getKeyCharacteristics() après avoir généré une clé avec le flag setIsStrongBoxBacked(true). L’attribut SECURITY_LEVEL_STRONGBOX confirme le support matériel. Si l’appareil ne prend pas en charge StrongBox, Keystore revient à TEE sans erreur — vous devez vérifier explicitement le niveau de sécurité.
Les clés dans Keystore sont automatiquement supprimées lors de la désinstallation de l’application. Sur Android 10+, les clés peuvent persister si l’application a le flag allowBackup=true dans son manifeste, mais elles seront indisponibles après réinstallation. Il est recommandé de générer à nouveau les clés lors d’une installation propre.
Non, Android Keystore est lié au matériel d’un appareil spécifique. Une clé générée dans le TEE d’un appareil ne peut pas être transférée sur un autre. Pour le chiffrement multiplateforme, utilisez le schéma : Keystore protège la clé sur l’appareil, et les clés de session sont transmises via une API sécurisée utilisant le chiffrement asymétrique.
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.
Lisez aussi