Android Keystore — een cryptografische provider die versleutelingssleutels genereert en opslaat in een geïsoleerde uitvoeringsomgeving (TEE), die zelfs voor het besturingssysteem ontoegankelijk is. Volgens AOSP Security Documentation (2025) wordt Keystore gebruikt in meer dan 80% van de Android-apps uit de top 100 van Google Play voor de bescherming van tokens en gegevensversleuteling. Inzicht in Android Keystore is van cruciaal belang voor het veilig opslaan van sleutels op Android.
Belangrijkste
Android Keystore — een systeemcomponent van het Android-platform die een API biedt voor het genereren, opslaan en gebruiken van cryptografische sleutels in een beveiligde omgeving. In tegenstelling tot software-cryptografische bibliotheken (Bouncy Castle, Conscrypt) garandeert Keystore dat privésleutels nooit het geïsoleerde uitvoeringsgebied verlaten.
Keystore verscheen in Android 4.3 (API 18) als een softwareprovider met RSA-ondersteuning. Vanaf Android 6.0 (API 23) kreeg Keystore hardware-ondersteuning via Keymaster Hardware Abstraction Layer (HAL), die cryptografische bewerkingen delegeert naar Trusted Execution Environment (TEE) op compatibele apparaten. Volgens Android Compatibility Definition Document (2025) moeten alle apparaten met Android 9+ hardware-Keystore ondersteunen via TEE of StrongBox.
Sleutels in Keystore worden geïdentificeerd door een alias — een tekenreeks die wordt doorgegeven bij het aanmaken of laden van de sleutel. Keystore staat niet toe dat het ruwe sleutelmateriaal wordt verkregen: getEncoded()-methoden retourneren null voor sleutels die in Keystore zijn gemaakt. Dit is een fundamenteel verschil met softwaresleutels — een aanvaller kan de privésleutel niet extraheren, zelfs niet met volledige controle over het apparaat.
Keystore is geïntegreerd met andere beveiligingsmechanismen van Android: biometrische authenticatie (BiometricPrompt), versleuteling op bestandsniveau (File-Based Encryption) en verificatiefuncties SafetyNet / Play Integrity. Sleutels kunnen worden geconfigureerd voor automatische verwijdering onder bepaalde voorwaarden: bij het verwijderen van de codepin, bij het toevoegen van een nieuwe vingerafdruk of bij het verlopen van de geldigheidsduur.
De architectuur van Android Keystore omvat drie implementatieniveaus die verschillen in de mate van hardwarebeveiliging. Het niveau hangt af van de hardwaremogelijkheden van het apparaat.
TEE (Trusted Execution Environment) — een geïsoleerd gebied dat parallel met het hoofd besturingssysteem op dezelfde processor werkt. TEE gebruikt ARM TrustZone-technologie, die de fysieke processorkern splitst in twee virtuele delen: Normal World (Android) en Secure World (TEE). Code in Secure World heeft toegang tot geheugen en randapparatuur die vanuit Normal World niet toegankelijk zijn.
Wanneer een app een cryptografische bewerking aanroept via Keystore, wordt het verzoek via Keymaster HAL naar TEE gestuurd, waar de bewerking hardwarematig wordt uitgevoerd. Het resultaat wordt teruggegeven aan de app, maar de privésleutel blijft in het beveiligde geheugen van TEE. TEE is gecertificeerd volgens GlobalPlatform TEE Protection Profile en is een verplichte vereiste voor Android 9+ op apparaten met processors die TrustZone ondersteunen.
TEE ondersteunt de algoritmen AES/GCM (128, 256 bits), RSA (2048, 4096 bits), EC (P-256, P-384, P-521) en HMAC-SHA256. De prestaties van TEE zijn lager dan die van software-cryptografie (20–40% lager), maar voor typische bewerkingen (JWT-ondertekening, ontsleuteling van sessiesleutel) bedraagt de vertraging niet meer dan 10–50 ms.
StrongBox — een speciale beveiligingschip, fysiek gescheiden van de hoofdprocessor. In tegenstelling tot TEE, dat processortijd deelt met Android, heeft StrongBox een eigen CPU, RAM, True Random Number Generator (TRNG) en beveiligde opslag (One-Time Programmable memory). StrongBox is gecertificeerd volgens Common Criteria EAL 4+ en Secure IC Protection Profile.
StrongBox is beschikbaar op apparaten met Android 9+ mits een geschikte chip aanwezig is (bijv. Titan M op Google Pixel, Knox op Samsung Galaxy). De ontwikkelaar activeert StrongBox via de vlag setIsStrongBoxBacked(true) in KeyGenParameterSpec. Bij afwezigheid van hardware-ondersteuning wordt de vlag genegeerd en schakelt Keystore over naar TEE.
Beperkingen van StrongBox: ondersteunt een beperkte set algoritmen (AES-256, EC P-256, HMAC-SHA256), bewerkingswachtrij — maximaal één tegelijk, aantal bewerkingen — beperkt door chipbronnen. StrongBox is niet bedoeld voor scenario's met hoge belasting — gebruik TEE voor frequente bewerkingen en StrongBox alleen voor kritieke sleutels (master-versleutelingssleutels, ondertekeningssleutels).
Software-based Keystore — een software-implementatie die wordt gebruikt op apparaten zonder hardware-ondersteuning voor TEE of StrongBox. Sleutels worden versleuteld opgeslagen in het bestandssysteem, maar de privésleutel kan tijdelijk worden ontsleuteld in het RAM. Software-Keystore is minder veilig — een aanvaller met root-toegang kan de sleutel in het geheugen onderscheppen.
Vanaf Android 12 (API 31) vereist Google hardware-ondersteuning voor Keystore voor alle nieuwe apparaten. Apparaten met Android 9–11 kunnen software-Keystore hebben op budgetmodellen. De ontwikkelaar kan het beveiligingsniveau controleren via KeyStore.getKeyCharacteristics() — het attribuut SECURITY_LEVEL_TRUSTED_ENVIRONMENT of SECURITY_LEVEL_STRONGBOX bevestigt hardwarebeveiliging.
Android Keystore ondersteunt een breed scala aan cryptografische algoritmen, verdeeld in categorieën op basis van het sleuteltype. De keuze van het algoritme beïnvloedt de prestaties, compatibiliteit en het beveiligingsniveau.
AES (Advanced Encryption Standard) — symmetrische versleuteling voor de bescherming van gegevens op het apparaat. Aanbevolen modus: AES/GCM/NoPadding (256 bits). GCM biedt geverifieerde versleuteling (AEAD) — controle van de integriteit van versleutelde gegevens. IV-grootte (Initialisatievector): 12 bytes voor GCM. Gebruik geen AES/ECB — het biedt onvoldoende bescherming.
RSA (Rivest–Shamir–Adleman) — asymmetrische versleuteling voor de bescherming van sessiesleutels en digitale handtekeningen. Aanbevolen grootte: 2048 of 4096 bits. Modi: RSA/ECB/PKCS1Padding (versleuteling) en RSA/ECB/PKCS1Sign (ondertekening). RSA 1024 wordt als verouderd beschouwd en wordt niet aanbevolen voor nieuwe toepassingen (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — asymmetrische cryptografie op elliptische curven voor ondertekening en sleuteluitwisseling. Ondersteunde curven: secp256r1 (P-256, verplicht), secp384r1 (P-384) en secp521r1 (P-521). EC biedt vergelijkbare beveiliging als RSA met een aanzienlijk kleinere sleutelgrootte. P-256 wordt aanbevolen voor de meeste scenario's: het wordt ondersteund door alle apparaten en biedt een beveiligingsniveau van 128 bits.
HMAC (Hash-based Message Authentication Code) — symmetrische berichtauthenticatie. Ondersteunde hash-functies: SHA-256, SHA-384, SHA-512. HMAC wordt gebruikt voor het verifiëren van de integriteit en authenticiteit van gegevens, bijvoorbeeld voor het verifiëren van webhook-verzoeken of het controleren van de configuratie-integriteit.
Alle algoritmen kunnen worden gekoppeld aan biometrische authenticatie via KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). Op Android 11+ is de vlag setUserAuthenticationParameters() beschikbaar met een time-out (in seconden) waarna de sleutel beschikbaar is na biometrische authenticatie, zonder herhaalde aanvraag.
Laten we praktische voorbeelden bekijken van werken met Android Keystore in Kotlin: het genereren van een AES-sleutel, het versleutelen van gegevens en het maken van een asymmetrisch paar voor ondertekening.
Het voorbeeld maakt een 256-bits AES/GCM-sleutel met koppeling aan biometrische authenticatie. De sleutel is niet beschikbaar voor export 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()
}
Het voorbeeld versleutelt gegevens met behulp van een sleutel uit Android Keystore. Cipher haalt de sleutel op via alias, initialiseert AES/GCM-versleuteling en retourneert de versleutelde gegevens samen met 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 + versleutelde gegevens
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)
}
Het voorbeeld maakt een paar RSA-2048-sleutels in Keystore met koppeling aan StrongBox. De privésleutel wordt gebruikt voor ondertekening, de openbare sleutel kan worden geëxporteerd 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()
// Openbare sleutel kan worden geëxporteerd
val publicKey = pair.public // X509EncodedKeySpec
}
Effectief gebruik van Android Keystore vereist naleving van regels die maximale bescherming bieden met behoud van prestaties.
Gebruik KeyGenParameterSpec met minimaal noodzakelijke parameters: geef alleen die purpose, block modes en paddings op die daadwerkelijk worden gebruikt. Overmatige parameters (bijv. PURPOSE_ENCRYPT voor een sleutel die alleen voor ondertekening wordt gebruikt) creëren extra aanvalsvectoren. Android raadt aan om expliciet de digest voor ondertekening op te geven — SHA256 is het minimaal acceptabele niveau (SHA1 is verouderd).
Koppel sleutels aan biometrie voor kritieke bewerkingen: setUserAuthenticationRequired(true) garandeert dat de sleutel alleen kan worden gebruikt na biometrische authenticatie. Gebruik op Android 11+ setUserAuthenticationParameters() met een time-out (aanbevolen 30–60 seconden) om niet voor elke bewerking binnen één sessie biometrie te vragen. setInvalidatedByBiometricEnrollment(true) verwijdert automatisch de sleutel bij het toevoegen van een nieuwe vingerafdruk of gezicht — dit voorkomt toegang met oude biometrische gegevens.
Controleer het beveiligingsniveau in de initialisatiefase: gebruik KeyStore.getKeyCharacteristics() om SECURITY_LEVEL te bepalen. Als het apparaat alleen software-Keystore ondersteunt (SECURITY_LEVEL_SOFTWARE), neem dan een beslissing: ofwel de functionaliteit weigeren, ofwel extra versleuteling gebruiken (bijv. de sleutel inpakken met het wachtwoord van de gebruiker). Vertrouw niet op StrongBox als deze niet gegarandeerd is — geef altijd de vlag setIsStrongBoxBacked(true) op en controleer het resultaat via getKeyCharacteristics.
Werk sleutels volgens schema bij: cryptografische sleutels hebben een aanbevolen levensduur. NIST SP 800-57 raadt aan AES-sleutels elke 1–2 jaar te vervangen, RSA/EC-paren elke 2–3 jaar. Implementeer een sleutelrotatiemechanisme: controleer bij het starten van de app de aanmaakdatum van de sleutel (KeyGenParameterSpec.Builder.setKeyValidityStart/End) en genereer een nieuwe sleutel bij het verlopen van de termijn. Oude gegevens die met de oude sleutel zijn versleuteld, moeten worden ontsleuteld en opnieuw versleuteld met de nieuwe.
Gebruik Keystore niet voor grote gegevens: Keystore is bedoeld voor het opslaan van sleutels (enkele honderden bytes), niet voor het versleutelen van grote bestanden. Gebruik voor gegevensversleuteling het schema: genereer een willekeurige AES-sleutel (DEK — Data Encryption Key), versleutel de gegevens met deze sleutel en versleutel DEK met de Keystore-sleutel (KEK — Key Encryption Key). Android EncryptedSharedPreferences gebruikt precies dit schema: de master-sleutel in Keystore, gegevens — AES-256 GCM.
Veelgestelde vragen
Nee, Android Keystore is zo ontworpen dat de privésleutel nooit TEE of StrongBox verlaat. De methode getEncoded() retourneert null voor sleutels die in Keystore zijn gemaakt. De sleutel kan alleen worden gebruikt via Cipher, Signature of Mac API — het ruwe materiaal is niet beschikbaar.
TEE (TrustZone) — virtuele isolatie op dezelfde processor, gebruikt tijdsdeling. StrongBox — een aparte chip met eigen CPU en geheugen. StrongBox is veiliger (Common Criteria EAL 4+), maar langzamer en ondersteunt minder algoritmen. TEE is geschikt voor frequente bewerkingen, StrongBox voor kritieke sleutels.
Gebruik KeyStore.getKeyCharacteristics() na het genereren van een sleutel met de vlag setIsStrongBoxBacked(true). Het attribuut SECURITY_LEVEL_STRONGBOX bevestigt hardware-ondersteuning. Als het apparaat StrongBox niet ondersteunt, schakelt Keystore zonder foutmelding over naar TEE — u moet expliciet het beveiligingsniveau controleren.
Sleutels in Keystore worden automatisch verwijderd wanneer de app van het apparaat wordt verwijderd. Op Android 10+ kunnen sleutels behouden blijven als de app de vlag allowBackup=true in het manifest heeft, maar ze zijn niet toegankelijk na herinstallatie. Het wordt aanbevolen om bij een schone installatie nieuwe sleutels te genereren.
Nee, Android Keystore is gebonden aan de hardware van een specifiek apparaat. Een sleutel gegenereerd in de TEE van het ene apparaat kan niet naar een ander worden overgebracht. Gebruik voor platformoverschrijdende versleuteling het schema: Keystore beschermt de sleutel op het apparaat en sessiesleutels worden verzonden via een beveiligde API met asymmetrische versleuteling.
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