Keystore (Android) : ce que c'est, architecture et principes de fonctionnement

Auteur : IT Sectr Publié le : 2026-03-14 Temps de lecture : 10 min

Android Keystore est un mécanisme système sous Android permettant de stocker en toute sécurité des clés cryptographiques dans un isolement matériel. Le système utilise Trusted Execution Environment (TEE) sur les appareils avec ARM TrustZone ou un Secure Element dédié pour protéger les clés au niveau de la puce. Selon Android Open Source Project, Keystore prend en charge les algorithmes RSA, EC, AES et HMAC avec génération de clés directement dans l'environnement sécurisé.

Points clés

  • Android Keystore est un fournisseur KeyStore qui isole les clés cryptographiques de l'espace utilisateur Android
  • Les clés sont générées dans TEE ou Secure Element et ne quittent jamais l'environnement sécurisé en texte clair
  • Android 9+ ajoute KeyGenParameterSpec.Builder avec des paramètres : purpose, digest, padding, userAuthenticationRequired
  • La protection biométrique des clés nécessite une confirmation de l'utilisateur via BiometricPrompt avant chaque opération
  • Keymaster HAL est une couche d'abstraction matérielle qui implémente les opérations cryptographiques dans TEE ou Secure Element

Qu'est-ce qu'Android Keystore ?

Android Keystore est un fournisseur cryptographique implémenté dans Android depuis l'API 1 (Android 1.0), mais le support matériel complet est apparu avec Android 4.3 (API 18). Keystore résout le problème du stockage sécurisé des clés privées de sorte que même si le système d'exploitation est compromis, un attaquant ne puisse pas extraire les clés en texte clair.

Architecture de KeyStore sous Android

L'architecture Android Keystore se compose de trois niveaux : l'API applicative (java.security.KeyStore), le service système (keystore daemon) et le niveau matériel (Keymaster HAL). L'application accède via l'API standard Java Cryptography Architecture (JCA), et le service système achemine les requêtes vers Keymaster exécuté dans TEE.

Toutes les opérations cryptographiques avec les clés (signature, déchiffrement) sont effectuées dans TEE ou Secure Element. Les clés ne quittent jamais l'environnement sécurisé — l'application reçoit seulement un handle (alias) pour référencer la clé. C'est une différence fondamentale avec les KeyStores logiciels où les clés sont potentiellement accessibles dans la mémoire du processus.

Différence avec Java KeyStore

Le JKS (Java KeyStore) standard ou BKS (Bouncy Castle) stockent les clés dans des fichiers protégés par mot de passe. Android Keystore stocke les clés dans un isolement matériel, où elles sont protégées même de l'utilisateur root. JKS est vulnérable à l'accès direct au système de fichiers ; Android Keystore ne l'est pas.

Autre différence : dans Android Keystore, les clés ont des paramètres d'utilisation stricts (purpose — uniquement sign/verify/encrypt/decrypt) spécifiés à la génération. Ils ne peuvent pas être modifiés ultérieurement, ce qui empêche l'utilisation abusive de la clé.

Comment fonctionne Android Keystore ?

Lors de la création d'une nouvelle clé, l'application appelle KeyPairGenerator ou KeyGenerator avec KeyGenParameterSpec, qui contient tous les paramètres de la future clé. Le système transmet la requête à Keymaster HAL, qui génère la clé dans TEE et retourne un handle.

Processus de génération de clé

La méthode KeyGenParameterSpec.Builder accepte des paramètres obligatoires : nom de la clé dans Keystore, objet (PURPOSE_SIGN, PURPOSE_ENCRYPT), algorithme (RSA, EC, AES). Supplémentaires : digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biométrie), keyValidityStart/End (restrictions temporelles).

Après définition des paramètres, KeyPairGenerator.generateKeyPair() retourne une KeyPair, où PrivateKey est un objet déléguant les opérations à Keymaster. La clé publique peut être extraite, la clé privée non. Elle existe seulement dans TEE.

kotlin
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties

fun generateKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
     .setUserAuthenticationRequired(true)
     .build()

    val kpGen = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_RSA,
        "AndroidKeyStore"
    )
    kpGen.initialize(spec)
    kpGen.generateKeyPair()
}

Signature et vérification

Signature pour ECDSA ou RSA-PSS est créée via l'API standard : Signature.getInstance(algorithm).initSign(privateKey). L'opération de signature est exécutée dans TEE : l'application transmet les données, Keymaster les signe matériellement et retourne la signature. La clé et les données ne se mélangent pas dans la mémoire partagée.

Pour la protection biométrique, l'utilisateur doit s'authentifier via BiometricPrompt avant de signer. Sans authentification réussie, Keymaster n'exécute pas l'opération et retourne CryptoAuthenticationException.

kotlin
import java.security.KeyStore
import java.security.Signature
import androidx.biometric.BiometricPrompt

fun signWithBiometric(alias: String) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val entry = ks.getEntry(alias, null) as KeyStore.PrivateKeyEntry
    val signature = Signature.getInstance("SHA256withRSA")
    signature.initSign(entry.privateKey)
    // BiometricPrompt avec CryptoObject(signature) demande FaceID/PIN
}

Types de stockage KeyStore

Android prend en charge deux modes de stockage de clés : logiciel (sur les appareils sans TEE) et matériel (sur les appareils avec TEE ou Secure Element). Le mode dépend des capacités du SoC et de la version d'Android.

KeyStore logiciel (logiciel uniquement)

Sur les appareils sans Trusted Execution Environment (antérieurs à Android 4.3 ou SoCs d'entrée de gamme), les clés sont stockées chiffrées à l'aide d'une clé maître dérivée du mot de passe de l'écran de verrouillage. Ce mode est moins sûr — les clés sont accessibles dans la mémoire du processus lors des opérations cryptographiques.

Le niveau de protection est basé sur le chiffrement du fichier KeyStore avec AES-256-GCM. La clé de chiffrement est générée à partir du mot de passe ou du code PIN de l'utilisateur via Scrypt (PBKDF2 avec un nombre élevé d'itérations).

KeyMaster matériel (TEE/Secure Element)

Sur les appareils modernes, Keymaster 4.x est utilisé dans TEE (ARM TrustZone). Les clés sont générées, stockées et utilisées exclusivement dans TrustZone. Même le noyau Linux n'a pas accès aux clés privées — seul Keymaster HAL peut effectuer des opérations.

Secure Element (par exemple, eSE dans Samsung Knox ou StrongBox dans Google Pixel 3+) est une puce séparée avec son propre processeur et sa propre mémoire. Il est certifié Common Criteria EAL 4+ et offre le niveau de protection maximal, y compris la protection contre l'altération physique.

TypeEmplacement de stockageNiveau de protectionDisponible depuis API
LogicielFichier /data/misc/keystoreMoyen (AES-256)API 1+
Keymaster 3TEE (TrustZone)ÉlevéAPI 23+
Keymaster 4TEE + Secure I/OTrès élevéAPI 28+
StrongBoxSecure Element matérielMaximumAPI 28+, optionnel

Travailler avec l'API KeyStore

Android Keystore est intégré dans Java Cryptography Architecture (JCA). Pour accéder au fournisseur, on utilise KeyStore.getInstance("AndroidKeyStore"). L'API est disponible depuis l'API 18.

Création et chargement du KeyStore

La méthode KeyStore.load(null) charge le conteneur KeyStore de l'application. Aucun mot de passe n'est requis — Android utilise le contexte de l'application et son UID pour le contrôle d'accès. Chaque application voit seulement ses propres entrées, sauf si un UID partagé est utilisé.

Les méthodes setEntry et getEntry fonctionnent avec KeyStore.PrivateKeyEntry, SecretKeyEntry ou TrustedCertificateEntry. Le paramètre ProtectionParameter est toujours null pour Android Keystore (la protection est implémentée au niveau système).

kotlin
import java.security.KeyStore
import java.security.cert.Certificate
import android.security.keystore.KeyProtection

fun storeSecretKey(alias: String, key: SecretKey) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val prot = KeyProtection.Builder(
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setUserAuthenticationRequired(true)
     .build()
    ks.setEntry(alias, KeyStore.SecretKeyEntry(key), prot)
}

Vérification du type de stockage

À l'aide de KeyCharacteristics, on peut déterminer dans quel environnement la clé est stockée : KeyStore logiciel, TEE ou StrongBox. La méthode getKeyCharacteristics() retourne un ensemble de drapeaux : FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biométrie).

Algorithmes et sécurité

Android Keystore prend en charge une large gamme d'algorithmes cryptographiques divisés en trois catégories : asymétriques, symétriques et MAC. La prise en charge d'algorithmes spécifiques dépend de la version de Keymaster HAL.

Algorithmes pris en charge

RSA (1024–4096 bits) — pour la signature (PKCS1, PSS) et le chiffrement (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — pour la signature ECDSA et l'échange de clés ECDH. AES (128, 256 bits) — pour le chiffrement symétrique en modes CBC, CTR, GCM. HMAC (SHA1, SHA256, SHA512) — pour l'authentification de messages.

Pour chaque clé, setPurposes est spécifié pour restreindre les opérations possibles. Une clé RSA avec PURPOSE_SIGN ne peut pas être utilisée pour le chiffrement, même si un attaquant a accès à l'API. C'est une application de l'utilisation de la clé au niveau matériel.

Protection contre la compromission

Keymaster inclut un compteur de tentatives d'authentification biométrique échouées. Après un nombre spécifié d'échecs (configurable via setInvalidatedByBiometricEnrollment), la clé devient indisponible et nécessite une suppression/régénération. Lorsque tous les modèles biométriques sont supprimés, toutes les clés avec userAuthenticationRequired=true sont automatiquement invalidées.

Key Attestation (Android 8.1+) est également prise en charge : à la demande de l'application, Keymaster signe un certificat avec des informations sur les caractéristiques de la clé (matériel/logiciel, algorithme, objets). Le serveur peut vérifier ce certificat pour confirmer que la clé a été créée dans un environnement de confiance.

Foire aux questions

Quelle est la différence entre Android Keystore et Java KeyStore ?

Java KeyStore stocke les clés dans un fichier protégé par mot de passe (JKS, BKS). Android Keystore utilise l'isolement matériel via TEE ou Secure Element. Java KeyStore est vulnérable à l'accès root ; Android Keystore ne l'est pas, car les clés privées ne quittent jamais l'environnement sécurisé.

Peut-on importer une clé existante dans Android Keystore ?

Oui, via KeyStore.setEntry avec KeyProtection. Cependant, la clé importée n'aura pas de protection matérielle — elle sera stockée dans le Keystore logiciel, chiffrée avec une clé maître. Pour une sécurité maximale, générez toujours les clés dans Keystore.

Comment vérifier si un appareil prend en charge le KeyStore matériel ?

Utilisez KeyChain.isBoundKeyAlgorithm ou vérifiez KeyCharacteristics après la génération de la clé. La présence de FLAG_HARDWARE dans les caractéristiques signifie que la clé a été créée dans TEE. Vous pouvez également vérifier android.security.keystore.isHardwareBacked().

Que deviennent les clés lors de la désinstallation de l'application ?

Lors de la désinstallation de l'application, Android supprime toutes ses clés du Keystore. Les données sont perdues irréversiblement. Lors de la réinstallation, l'application doit générer de nouvelles clés. La sauvegarde des clés via TEE est architecturalement impossible.

Comment KeyStore protège-t-il contre les attaques de débogage ?

Sur un appareil verrouillé, Keymaster n'effectue aucune opération. Les clés avec userAuthenticationRequired=true nécessitent une confirmation biométrique à chaque fois. Même avec un accès root, un attaquant ne peut pas appeler Keymaster directement — seulement via le service Android Keystore.

Résumé

  • Android Keystore est un fournisseur cryptographique JCA avec isolement matériel des clés via TEE ou Secure Element
  • Les clés sont générées dans TrustZone et ne quittent jamais l'environnement sécurisé en texte clair
  • KeyGenParameterSpec définit les paramètres de la clé : purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL implémente trois niveaux : logiciel, TEE (Keymaster 3/4) et StrongBox (Secure Element matériel)
  • La protection biométrique des clés est assurée via setUserAuthenticationRequired et BiometricPrompt avec CryptoObject
  • Key Attestation (API 28+) permet la vérification côté serveur que la clé a été créée dans un environnement matériel
  • Utilisez Android Keystore pour stocker les clés privées pour la signature, le chiffrement et l'authentification dans les applications Android

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.

Discuter du projet

Lisez aussi