KeyStore (Android) : concepts clés, API et fonctionnement du stockage cryptographique

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

KeyStore (Android) est une implémentation du fournisseur cryptographique Java Cryptography Architecture (JCA) intégrée à Android pour le stockage sécurisé de clés avec capacité d'isolation matérielle. Depuis Android 4.3 (API 18), KeyStore prend en charge les clés matérielles via Keymaster HAL, et à partir d'Android 9 (API 28), StrongBox Keymaster pour les clés dans un Secure Element dédié. Selon la Documentation de sécurité Android, le fournisseur « AndroidKeyStore » remplace le Bouncy Castle ou OpenSSL KeyStore standard, offrant une protection au niveau système contre l'extraction non autorisée de clés.

Points clés

  • Android KeyStore est un fournisseur JCA pour le stockage de clés avec prise en charge de TEE, StrongBox et protection biométrique
  • KeyGenParameterSpec définit l'algorithme, l'objectif, le digest, le padding et la biométrie lors de la création d'une clé
  • Keymaster HAL implémente les opérations cryptographiques matérielles aux niveaux Software, TEE et StrongBox
  • Key Attestation (API 28+) permet au serveur de vérifier que la clé a été créée dans un environnement matériel Android KeyStore
  • Alias de clé est une chaîne par laquelle l'application accède à la clé dans Keystore ; un alias correspond à une clé

Qu'est-ce que KeyStore dans Android ?

KeyStore dans Android n'est pas une application ou un fichier séparé, mais un fournisseur cryptographique implémentant l'interface java.security.KeyStore. Il fournit une API unifiée pour stocker et utiliser les clés privées, les clés symétriques et les certificats CA de confiance. Le fournisseur est enregistré sous le nom « AndroidKeyStore » et est accessible via KeyStore.getInstance() standard.

Évolution d'Android KeyStore

Avant Android 4.3, les opérations cryptographiques étaient effectuées via Bouncy Castle. Android 4.3 a introduit Keymaster HAL 1.0, permettant l'utilisation de TEE sur ARM TrustZone. Android 6.0 (API 23) a ajouté Keymaster 2.0 avec authentification biométrique matérielle. Android 9 (API 28) a présenté Keymaster 4.0 et StrongBox Keymaster pour un Secure Element dédié.

Chaque version de Keymaster ajoute de nouvelles capacités et améliore l'isolation des clés. Les appareils modernes (2022+) doivent prendre en charge Keymaster 4.0 pour la certification Google Mobile Services, garantissant ainsi la disponibilité de TEE pour toutes les applications Android.

Architecture et composants

Android KeyStore se compose de trois couches : API Java (KeyStore, KeyPairGenerator), processus système keystore (C++, exécuté en tant que service système) et Keymaster HAL (bibliothèque dans TEE ou Secure Element). L'application appelle l'API, le service keystore achemine la requête vers Keymaster et l'opération est exécutée dans l'environnement sécurisé.

Toutes les clés privées sont stockées dans le TEE et ne peuvent pas être lues depuis l'espace utilisateur. Même le service keystore système n'a pas accès aux clés brutes — seulement aux handles pointant vers les clés à l'intérieur de Keymaster.

Comment KeyStore fonctionne-t-il comme fournisseur cryptographique ?

Android KeyStore implémente l'interface standard de fournisseur de services JCA. Lorsqu'une application appelle Cipher.getInstance(« RSA/ECB/PKCS1Padding », « AndroidKeyStore »), le fournisseur de sécurité Android délègue l'opération à Keymaster via la chaîne : Java → JNI → service keystore → Keymaster HAL.

Enregistrement du fournisseur

Le fournisseur AndroidKeyStore est enregistré automatiquement au démarrage du processus. Sa priorité est supérieure à celle de Bouncy Castle ou Conscrypt. Par conséquent, lors de l'appel de KeyStore.getInstance() sans spécifier de fournisseur, AndroidKeyStore est retourné dans la plupart des cas. Pour un appel explicite, utilisez KeyStore.getInstance(« AndroidKeyStore »).

Chaque application Android dispose d'un conteneur isolé dans KeyStore. Les applications ayant le même UID (shared userId) peuvent partager l'accès à certaines clés, mais la configuration standard garantit que l'application A ne peut pas lire les clés de l'application B.

Méthodes de KeyStore et leurs particularités

load(null) — initialisation de KeyStore. Le paramètre est toujours null pour AndroidKeyStore. setEntry — enregistre une clé avec KeyProtection spécifiée (objectifs, digest, padding). getEntry — récupère KeyStore.PrivateKeyEntry, SecretKeyEntry ou TrustedCertificateEntry. containsAlias — vérifie si une clé existe. deleteEntry — supprime définitivement une clé.

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

object KeyStoreManager {
    private val keyStore by lazy {
        KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
    }

    fun createRsaKey(alias: String) {
        val spec = KeyGenParameterSpec.Builder(alias,
            KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
        ).setKeySize(2048)
         .setDigests(KeyProperties.DIGEST_SHA256)
         .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
         .build()

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

Algorithmes et types de clés pris en charge

Android KeyStore prend en charge un large ensemble d'algorithmes cryptographiques, variant selon la version de Keymaster HAL sur l'appareil. Un développeur peut obtenir la liste des algorithmes pris en charge via KeyGenParameterSpec.Builder lors de la tentative de génération — les paramètres incompatibles lèvent InvalidAlgorithmParameterException.

Algorithmes asymétriques

RSA (1024–4096 bits) — pour la signature (PKCS1, PSS avec SHA-1/SHA-256/SHA-384/SHA-512) et le chiffrement (OAEP avec SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — pour la signature ECDSA et l'échange de clés ECDH. X25519 et Ed25519 — depuis Android 12 (API 31) pour les protocoles cryptographiques modernes.

Pour les clés asymétriques, générez toujours à l'intérieur de Keymaster, N'importez JAMAIS de clés privées. Les clés privées importées ne sont pas protégées matériellement — elles sont stockées dans la couche logicielle et sont vulnérables si le processus de l'application est compromis.

Algorithmes symétriques

AES (128, 256 bits) — pour le chiffrement symétrique en modes CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — pour l'authentification de messages. ChaCha20 (Android 12+) — pour le chiffrement de flux haute performance avec authentification Poly1305.

AlgorithmeKeymasterObjectifAPI
RSAKM 1.0+Signature, Chiffrement18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+Chiffrement symétrique23+
HMACKM 2.0+Code d'authentification23+
ChaCha20KM 3.0+Chiffrement de flux31+
X25519/Ed25519KM 3.0+Échange de clés31+

Types de clés et leur sérialisation

KeyStore.PrivateKeyEntry — contient une clé privée (non exportable) et une chaîne de certificats. KeyStore.SecretKeyEntry — pour les clés symétriques. KeyStore.TrustedCertificateEntry — pour les certificats CA de confiance. Les clés publiques sont exportables via keyStore.getCertificate(alias).publicKey.

Exemples de génération et d'utilisation de clés

Examinons un scénario complet : générer une clé AES pour le chiffrement de données et générer une clé EC pour la signature avec protection biométrique. Les deux clés sont créées dans Android KeyStore avec prise en charge matérielle.

Génération d'une clé AES pour le chiffrement

Une clé AES est créée via KeyGenerator avec KeyGenParameterSpec. Paramètres : PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (mode recommandé avec authentification), ENCRYPTION_PADDING_NONE (aucun padding nécessaire pour GCM).

kotlin
import javax.crypto.KeyGenerator
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec

fun generateAndEncrypt(alias: String, plainText: ByteArray): ByteArray {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setKeySize(256)
     .build()

    val kg = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    kg.initialize(spec)
    kg.generateKey()

    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    cipher.init(Cipher.ENCRYPT_MODE, getKeyFromStore(alias))
    return cipher.doFinal(plainText)
}

Signature avec protection biométrique

Une clé EC avec userAuthenticationRequired=true nécessite une authentification de l'utilisateur avant chaque opération de signature. Pour cela, BiometricPrompt avec CryptoObject contenant l'objet Signature est utilisé. Après une vérification biométrique réussie, Keymaster autorise l'opération.

kotlin
fun createBiometricSignKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN
    ).setAlgorithmParameterSpec(
        ECGenParameterSpec("secp256r1")
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setUserAuthenticationRequired(true)
     .setInvalidatedByBiometricEnrollment(true)
     .build()

    val kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC,
        "AndroidKeyStore"
    )
    kpg.initialize(spec)
    kpg.generateKeyPair()
}

KeyStore et sécurité de l'appareil

Android KeyStore fournit des garanties de sécurité au niveau matériel que les KeyStore logiciels (JKS, BKS) ne peuvent pas offrir. Les clés sont protégées au niveau du SoC, et même le contrôle total de l'espace utilisateur Android ne permet pas d'extraire la clé privée.

Key Attestation (Android 8.1+)

Key Attestation est un mécanisme qui permet à une application (et au serveur) de vérifier l'environnement dans lequel une clé a été créée. Android Keystore signe un certificat contenant une liste de caractéristiques de la clé : algorithme, taille, objectifs, matériel (True/False), origine (GENERATED, IMPORTED). Le serveur vérifie la chaîne de certificats jusqu'au certificat racine de Google.

C'est essentiel pour les applications financières : le serveur peut exiger que la clé ait été créée dans un environnement matériel (Hardware-Backed = True) et rejeter les clés créées dans un Keystore logiciel. Key Attestation prévient les attaques où un attaquant remplace le Keystore par un émulateur.

Invalidation des clés lors du changement de biométrie

setInvalidatedByBiometricEnrollment(true) signifie que Keymaster supprimera automatiquement la clé lorsque les modèles biométriques sont modifiés ou supprimés. Cela protège contre les attaques où un attaquant ajoute son empreinte digitale à un compte existant. Après l'ajout d'une nouvelle empreinte, les anciennes clés deviennent inaccessibles.

Le compteur de tentatives échouées d'authentification biométrique est également géré par Keymaster. Après maxBiometricAttempt (configurable par le fabricant, généralement 5), Keymaster bloque toutes les opérations avec des clés biométriques pendant 30 secondes. Après 10 tentatives échouées — jusqu'à la saisie du mot de passe de l'appareil (PIN secret).

Questions fréquentes

Quelle est la différence entre Android KeyStore et Bouncy Castle KeyStore ?

Bouncy Castle (BKS) est un KeyStore logiciel qui stocke les clés dans un fichier protégé par mot de passe. Android KeyStore utilise l'isolation matérielle TEE/StrongBox. Les clés BKS peuvent être extraites avec un accès root, les clés Android KeyStore non. BKS convient aux certificats CA, Android KeyStore aux clés privées.

Puis-je utiliser la même clé pour le chiffrement et la signature ?

Oui, si vous spécifiez PURPOSE_ENCRYPT ou PURPOSE_DECRYPT ou PURPOSE_SIGN ou PURPOSE_VERIFY lors de la génération. Cependant, la meilleure pratique est de créer des clés séparées pour différentes opérations. Cela limite les dégâts si une clé est compromise et respecte le principe du moindre privilège.

Comment savoir si une clé est matérielle dans Android KeyStore ?

Utilisez KeyStore.getKeyCharacteristics(alias), disponible via android.security.keystore. La méthode retourne un ensemble de drapeaux : FLAG_HARDWARE — clé dans TEE, FLAG_SECURE_ELEMENT — clé dans StrongBox. S'il n'y a pas de drapeaux, la clé est uniquement logicielle.

Que se passe-t-il lorsque tous les modèles biométriques sont supprimés ?

Toutes les clés créées avec setInvalidatedByBiometricEnrollment(true) seront automatiquement invalidées par Keymaster. Lors de la tentative d'utilisation, l'application recevra KeyPermanentlyInvalidatedException. Les données chiffrées avec ces clés seront perdues définitivement.

Android KeyStore prend-il en charge la sauvegarde des clés ?

Les clés matérielles (dans TEE/StrongBox) ne prennent pas en charge la sauvegarde — elles sont liées à un appareil spécifique. Les clés logicielles peuvent être incluses dans la sauvegarde Google Drive. Pour transférer des données entre appareils, chiffrez les données sur le serveur et déchiffrez sur le nouvel appareil.

Résumé

  • Android KeyStore — fournisseur JCA pour le stockage de clés isolé matériellement via Keymaster HAL dans TEE/StrongBox
  • KeyGenParameterSpec configure l'algorithme, la taille, les objectifs, le digest, la biométrie et les restrictions temporelles de la clé
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — algorithmes pris en charge avec différents niveaux Keymaster
  • Key Attestation (API 28+) permet au serveur de vérifier l'origine matérielle de la clé
  • Protection biométrique des clés via setUserAuthenticationRequired + BiometricPrompt avec CryptoObject
  • Invalidation des clés lors du changement biométrique empêche l'utilisation non autorisée des empreintes ajoutées
  • Utilisez Android KeyStore pour générer et stocker des clés cryptographiques avec protection matérielle 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