KeyStore (Android) — is een implementatie van de cryptografische provider Java Cryptography Architecture (JCA), geïntegreerd in Android voor veilige sleutelopslag met hardware-isolatie. Sinds Android 4.3 (API 18) ondersteunt KeyStore hardware-sleutels via Keymaster HAL, en vanaf Android 9 (API 28) — StrongBox Keymaster voor sleutels in een dedicated Secure Element. Volgens Android Security Documentation vervangt de provider „AndroidKeyStore” de standaard Bouncy Castle of OpenSSL KeyStore en biedt systeembescherming tegen ongeautoriseerde extractie van sleutels.
Belangrijkste punten
KeyStore in Android — is geen aparte applicatie of bestand, maar een cryptografische provider die de java.security.KeyStore-interface implementeert. Het biedt een uniforme API voor het opslaan en gebruiken van privésleutels, symmetrische sleutels en certificaten van vertrouwde certificeringsinstanties (CA). De provider is geregistreerd onder de naam „AndroidKeyStore” en toegankelijk via standaard KeyStore.getInstance().
Vóór Android 4.3 werden cryptografische bewerkingen softwarematig uitgevoerd via Bouncy Castle. Met Android 4.3 verscheen Keymaster HAL 1.0, waardoor TEE op ARM TrustZone kon worden gebruikt. Android 6.0 (API 23) voegde Keymaster 2.0 toe met ondersteuning voor hardware-authenticatie via vingerafdruk. Android 9 (API 28) introduceerde Keymaster 4.0 en StrongBox Keymaster voor een dedicated Secure Element.
Elke versie van Keymaster voegt nieuwe mogelijkheden toe en verbetert de isolatie van sleutels. Moderne apparaten (2022+) moeten Keymaster 4.0 ondersteunen voor Google Mobile Services-certificering, wat de aanwezigheid van TEE garandeert voor alle Android-applicaties.
Android KeyStore bestaat uit drie niveaus: Java API (KeyStore, KeyPairGenerator), het systeemproces keystore (C++, werkt als system service) en Keymaster HAL (bibliotheek in TEE of Secure Element). De applicatie roept de API aan, de keystore-service stuurt het verzoek door naar Keymaster en de bewerking wordt uitgevoerd in de beveiligde omgeving.
Alle privésleutels worden opgeslagen in TEE en kunnen niet worden uitgelezen vanuit de gebruikersruimte. Zelfs de systeem-keystore-service heeft geen toegang tot de ruwe sleutels — alleen tot handles die naar sleutels binnen Keymaster verwijzen.
Android KeyStore implementeert de standaard JCA-serviceproviderinterface. Wanneer de applicatie Cipher.getInstance(„RSA/ECB/PKCS1Padding”, „AndroidKeyStore”) aanroept, delegeert Android Security Provider de bewerking via de keten: Java → JNI → keystore service → Keymaster HAL.
De provider AndroidKeyStore wordt automatisch geregistreerd bij het opstarten van het proces. De prioriteit is hoger dan die van Bouncy Castle of Conscrypt. Daarom wordt bij het aanroepen van KeyStore.getInstance() zonder provider meestal AndroidKeyStore geretourneerd. Gebruik voor expliciete aanroep KeyStore.getInstance(„AndroidKeyStore”).
Elke Android-applicatie heeft een geïsoleerde container in KeyStore. Applicaties met dezelfde UID (shared userId) kunnen gedeelde toegang hebben tot bepaalde sleutels, maar de standaardconfiguratie garandeert dat applicatie A de sleutels van applicatie B niet kan lezen.
load(null) — initialisatie van KeyStore. De parameter is altijd null voor AndroidKeyStore. setEntry — opslaan van een sleutel met opgave van KeyProtection (purposes, digest, padding). getEntry — ophalen van KeyStore.PrivateKeyEntry, SecretKeyEntry of TrustedCertificateEntry. containsAlias — controleren of een sleutel bestaat. deleteEntry — verwijderen van een sleutel (onomkeerbaar).
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()
}
}
Android KeyStore ondersteunt een brede set cryptografische algoritmen, variërend afhankelijk van de Keymaster HAL-versie op het apparaat. De ontwikkelaar kan de lijst met ondersteunde algoritmen verkrijgen via KeyGenParameterSpec.Builder bij een generatiepoging — incompatibele parameters veroorzaken InvalidAlgorithmParameterException.
RSA (1024–4096 bit) — voor ondertekening (PKCS1, PSS met SHA-1/SHA-256/SHA-384/SHA-512) en versleuteling (OAEP met SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — voor ECDSA-ondertekening en ECDH-sleutelovereenkomst. X25519 en Ed25519 — vanaf Android 12 (API 31) voor moderne cryptografische protocollen.
Voor asymmetrische sleutels Genereer altijd binnen Keymaster, IMPORTEER NOOIT privésleutels. Geïmporteerde privésleutels zijn niet hardwarematig beveiligd — ze worden opgeslagen in de softwarelaag en zijn kwetsbaar bij compromittering van de AP.
AES (128, 256 bit) — voor symmetrische versleuteling in CBC-, CTR-, GCM-modus. HMAC (SHA-1, SHA-256, SHA-512) — voor berichtauthenticatie. ChaCha20 (Android 12+) — voor hoogwaardige stroomversleuteling met Poly1305-authenticatie.
| Algoritme | Keymaster | Doel | API |
|---|---|---|---|
| RSA | KM 1.0+ | Ondertekening, versleuteling | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Symmetrische versleuteling | 23+ |
| HMAC | KM 2.0+ | Authenticatiecode | 23+ |
| ChaCha20 | KM 3.0+ | Stroomversleuteling | 31+ |
| X25519/E25519 | KM 3.0+ | Sleuteluitwisseling | 31+ |
KeyStore.PrivateKeyEntry — bevat de privésleutel (niet exporteerbaar) en de certificaatketen. KeyStore.SecretKeyEntry — voor symmetrische sleutels. KeyStore.TrustedCertificateEntry — voor vertrouwde CA-certificaten. Openbare sleutels zijn beschikbaar voor export via keyStore.getCertificate(alias).publicKey.
Laten we een volledig scenario bekijken: het genereren van een AES-sleutel voor gegevensversleuteling en het genereren van een EC-sleutel voor ondertekening met biometrische beveiliging. Beide sleutels worden gemaakt binnen Android KeyStore met hardware-ondersteuning.
De AES-sleutel wordt aangemaakt via KeyGenerator met KeyGenParameterSpec. Parameters: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (aanbevolen modus met authenticatie), ENCRYPTION_PADDING_NONE (voor GCM is padding niet nodig).
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)
}
De EC-sleutel met userAuthenticationRequired=true vereist authenticatie van de gebruiker vóór elke ondertekeningsoperatie. Hiervoor wordt BiometricPrompt gebruikt met CryptoObject dat een Signature-object bevat. Na succesvolle biometrie staat Keymaster de bewerking toe.
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()
}
Android KeyStore biedt hardware beveiligingsgaranties die softwarematige KeyStores (JKS, BKS) niet kunnen bieden. Sleutels worden beschermd op SoC-niveau en zelfs volledige controle over de Android-gebruikersruimte maakt het niet mogelijk de privésleutel te extraheren.
Key Attestation — een mechanisme waarmee de applicatie (en server) kan verifiëren in welke omgeving de sleutel is gemaakt. Android Keystore ondertekent een certificaat met een lijst van sleuteleigenschappen: algoritme, grootte, purges, hardware-backed (True/False), origin (GENERATED, IMPORTED). De server verifieert de certificaatketen tot aan het rootcertificaat van Google.
Dit is cruciaal voor financiële applicaties: de server kan eisen dat de sleutel in een hardware-omgeving is gemaakt (Hardware-Backed = True) en sleutels uit software-Keystore weigeren. Key Attestation voorkomt aanvallen waarbij de aanvaller Keystore vervangt door een emulator.
setInvalidatedByBiometricEnrollment(true) betekent dat de sleutel automatisch wordt verwijderd door Keymaster bij wijziging of verwijdering van biometrische sjablonen van de gebruiker. Dit is bescherming tegen aanvallen waarbij de aanvaller zijn eigen vingerafdruk toevoegt aan een bestaand account. Na het toevoegen van een nieuwe vingerafdruk worden oude sleutels ontoegankelijk.
De teller van mislukte biometrische authenticatiepogingen wordt ook beheerd door Keymaster. Na maxBiometricAttempt (ingesteld door de fabrikant, meestal 5) blokkeert Keymaster alle bewerkingen met biometrische sleutels gedurende 30 seconden. Na 10 mislukte pogingen — tot het invoeren van het apparaatwachtwoord (geheime PIN).
Veelgestelde vragen
Bouncy Castle (BKS) — een software KeyStore die sleutels opslaat in een met een wachtwoord beveiligd bestand. Android KeyStore gebruikt hardware-isolatie TEE/StrongBox. BKS-sleutels kunnen worden geëxtraheerd met root-toegang, Android KeyStore-sleutels niet. BKS is geschikt voor CA-certificaten, Android KeyStore voor privésleutels.
Ja, als bij generatie PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY wordt opgegeven. De beste praktijk is echter om afzonderlijke sleutels te maken voor verschillende bewerkingen. Dit beperkt de schade bij compromittering van een van de sleutels en voldoet aan het principe vanminimale bevoegdheden.
Gebruik KeyStore.getKeyCharacteristics(alias), beschikbaar via android.security.keystore. De methode retourneert een set vlaggen: FLAG_HARDWARE — sleutel in TEE, FLAG_SECURE_ELEMENT — sleutel in StrongBox. Als er geen vlaggen zijn — is de sleutel softwarematig.
Alle sleutels die zijn gemaakt met setInvalidatedByBiometricEnrollment(true) worden automatisch ongeldig verklaard door Keymaster. Bij een gebruiksactie ontvangt de applicatie KeyPermanentlyInvalidatedException. Gegevens die met deze sleutels zijn versleuteld, zijn onherstelbaar verloren.
Hardware sleutels (in TEE/StrongBox) ondersteunen geen back-up — ze zijn gebonden aan het specifieke apparaat. Software-sleutels kunnen worden opgenomen in Google Drive-back-up. Voor het overzetten van gegevens tussen apparaten versleutelt u gegevens op de server en ontsleutelt u deze op het nieuwe apparaat.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook