KeyStore (Android) ist eine Implementierung des Kryptografieanbieters Java Cryptography Architecture (JCA), die in Android für die sichere Schlüsselspeicherung mit Hardware-Isolierungsmöglichkeiten integriert ist. Seit Android 4.3 (API 18) unterstützt KeyStore Hardwareschlüssel über Keymaster HAL und ab Android 9 (API 28) StrongBox Keymaster für Schlüssel in einem dedizierten Secure Element. Laut Android-Sicherheitsdokumentation ersetzt der Anbieter „AndroidKeyStore“ den standardmäßigen Bouncy Castle oder OpenSSL KeyStore und bietet systemweiten Schutz vor unbefugtem Schlüsselextrakt.
Wichtige Punkte
KeyStore in Android ist keine separate Anwendung oder Datei, sondern ein Kryptografieanbieter, der das java.security.KeyStore-Interface implementiert. Er bietet eine einheitliche API zum Speichern und Verwenden von privaten Schlüsseln, symmetrischen Schlüsseln und vertrauenswürdigen CA-Zertifikaten. Der Anbieter ist unter dem Namen „AndroidKeyStore“ registriert und über den standardmäßigen KeyStore.getInstance() zugänglich.
Vor Android 4.3 wurden kryptografische Operationen über Bouncy Castle durchgeführt. Android 4.3 führte Keymaster HAL 1.0 ein, das die Nutzung von TEE auf ARM TrustZone ermöglichte. Android 6.0 (API 23) fügte Keymaster 2.0 mit hardwaregestützter Fingerabdruckauthentifizierung hinzu. Android 9 (API 28) führte Keymaster 4.0 und StrongBox Keymaster für ein dediziertes Secure Element ein.
Jede Version von Keymaster fügt neue Funktionen hinzu und verbessert die Schlüsselisolation. Moderne Geräte (2022+) müssen Keymaster 4.0 für die Google Mobile Services-Zertifizierung unterstützen, was die TEE-Verfügbarkeit für alle Android-Anwendungen garantiert.
Android KeyStore besteht aus drei Schichten: Java-API (KeyStore, KeyPairGenerator), Systemprozess keystore (C++, wird als Systemdienst ausgeführt) und Keymaster HAL (Bibliothek in TEE oder Secure Element). Die Anwendung ruft die API auf, der Keystore-Dienst leitet die Anfrage an Keymaster weiter, und die Operation wird in der sicheren Umgebung ausgeführt.
Alle privaten Schlüssel werden in der TEE gespeichert und können aus dem Benutzerbereich nicht gelesen werden. Selbst der System-Keystore-Dienst hat keinen Zugriff auf die Rohschlüssel — nur auf Handles, die auf die Schlüssel innerhalb von Keymaster verweisen.
Android KeyStore implementiert das standardmäßige JCA-Dienstanbieter-Interface. Wenn eine Anwendung Cipher.getInstance(„RSA/ECB/PKCS1Padding“, „AndroidKeyStore“) aufruft, delegiert der Android-Sicherheitsanbieter die Operation über die Kette an Keymaster: Java → JNI → Keystore-Dienst → Keymaster HAL.
Der AndroidKeyStore-Anbieter wird automatisch beim Start des Prozesses registriert. Seine Priorität ist höher als die von Bouncy Castle oder Conscrypt. Daher wird bei Aufruf von KeyStore.getInstance() ohne Angabe eines Anbieters in den meisten Fällen AndroidKeyStore zurückgegeben. Für den expliziten Aufruf verwenden Sie KeyStore.getInstance(„AndroidKeyStore“).
Jede Android-Anwendung hat einen isolierten Container im KeyStore. Anwendungen mit derselben UID (shared userId) können gemeinsamen Zugriff auf bestimmte Schlüssel haben, aber die Standardkonfiguration garantiert, dass Anwendung A die Schlüssel von Anwendung B nicht lesen kann.
load(null) — Initialisierung des KeyStore. Der Parameter ist für AndroidKeyStore immer null. setEntry — speichert einen Schlüssel mit angegebenem KeyProtection (Zwecke, Digest, Padding). getEntry — ruft KeyStore.PrivateKeyEntry, SecretKeyEntry oder TrustedCertificateEntry ab. containsAlias — prüft, ob ein Schlüssel existiert. deleteEntry — löscht einen Schlüssel endgültig.
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 unterstützt eine breite Palette von kryptografischen Algorithmen, die je nach Keymaster HAL-Version auf dem Gerät variieren. Ein Entwickler kann die Liste der unterstützten Algorithmen über KeyGenParameterSpec.Builder beim Generierungsversuch abrufen — inkompatible Parameter lösen InvalidAlgorithmParameterException aus.
RSA (1024–4096 Bit) — zum Signieren (PKCS1, PSS mit SHA-1/SHA-256/SHA-384/SHA-512) und Verschlüsseln (OAEP mit SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — für ECDSA-Signatur und ECDH-Schlüsselvereinbarung. X25519 und Ed25519 — ab Android 12 (API 31) für moderne kryptografische Protokolle.
Generieren Sie asymmetrische Schlüssel immer innerhalb von Keymaster und importieren Sie NIEMALS private Schlüssel. Importierte private Schlüssel sind hardwaremäßig nicht geschützt — sie werden in der Softwareschicht gespeichert und sind gefährdet, wenn der Anwendungsprozess kompromittiert wird.
AES (128, 256 Bit) — zur symmetrischen Verschlüsselung in den Modi CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — zur Nachrichtenauthentifizierung. ChaCha20 (Android 12+) — zur leistungsstarken Stromverschlüsselung mit Poly1305-Authentifizierung.
| Algorithmus | Keymaster | Zweck | API |
|---|---|---|---|
| RSA | KM 1.0+ | Signieren, Verschlüsseln | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Symmetrische Verschlüsselung | 23+ |
| HMAC | KM 2.0+ | Authentifizierungscode | 23+ |
| ChaCha20 | KM 3.0+ | Stromverschlüsselung | 31+ |
| X25519/Ed25519 | KM 3.0+ | Schlüsselaustausch | 31+ |
KeyStore.PrivateKeyEntry — enthält einen privaten Schlüssel (nicht exportierbar) und eine Zertifikatskette. KeyStore.SecretKeyEntry — für symmetrische Schlüssel. KeyStore.TrustedCertificateEntry — für vertrauenswürdige CA-Zertifikate. Öffentliche Schlüssel können über keyStore.getCertificate(alias).publicKey exportiert werden.
Betrachten wir ein vollständiges Szenario: Erzeugung eines AES-Schlüssels zur Datenverschlüsselung und Erzeugung eines EC-Schlüssels zum Signieren mit biometrischem Schutz. Beide Schlüssel werden innerhalb von Android KeyStore mit Hardwareunterstützung erstellt.
Ein AES-Schlüssel wird über KeyGenerator mit KeyGenParameterSpec erstellt. Parameter: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (empfohlener Modus mit Authentifizierung), ENCRYPTION_PADDING_NONE (kein Padding für GCM erforderlich).
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)
}
Ein EC-Schlüssel mit userAuthenticationRequired=true erfordert eine Benutzerauthentifizierung vor jedem Signiervorgang. Dazu wird BiometricPrompt mit CryptoObject verwendet, das das Signature-Objekt enthält. Nach erfolgreicher biometrischer Überprüfung erlaubt Keymaster die Operation.
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 bietet Hardware-Level-Sicherheitsgarantien, die softwarebasierte KeyStores (JKS, BKS) nicht bieten können. Schlüssel werden auf SoC-Ebene geschützt, und selbst die vollständige Kontrolle über den Android-Benutzerbereich ermöglicht keine Extraktion des privaten Schlüssels.
Key Attestation ist ein Mechanismus, der es einer Anwendung (und einem Server) ermöglicht, die Umgebung zu überprüfen, in der ein Schlüssel erstellt wurde. Android Keystore signiert ein Zertifikat mit einer Liste von Schlüsseleigenschaften: Algorithmus, Größe, Zwecke, hardwaregestützt (True/False), Herkunft (GENERATED, IMPORTED). Der Server überprüft die Zertifikatskette bis zum Google-Root-Zertifikat.
Dies ist für Finanzanwendungen von entscheidender Bedeutung: Der Server kann verlangen, dass der Schlüssel in einer Hardware-Umgebung erstellt wurde (Hardware-Backed = True), und in einem softwarebasierten Keystore erstellte Schlüssel ablehnen. Key Attestation verhindert Angriffe, bei denen ein Angreifer den Keystore durch einen Emulator ersetzt.
setInvalidatedByBiometricEnrollment(true) bedeutet, dass Keymaster den Schlüssel automatisch löscht, wenn biometrische Vorlagen geändert oder entfernt werden. Dies schützt vor Angriffen, bei denen ein Angreifer seinen Fingerabdruck zu einem bestehenden Konto hinzufügt. Nach dem Hinzufügen eines neuen Fingerabdrucks werden alte Schlüssel unzugänglich.
Der Zähler für fehlgeschlagene biometrische Authentifizierungsversuche wird ebenfalls von Keymaster verwaltet. Nach maxBiometricAttempt (vom Hersteller konfigurierbar, normalerweise 5) blockiert Keymaster alle Operationen mit biometrischen Schlüsseln für 30 Sekunden. Nach 10 fehlgeschlagenen Versuchen — bis zur Eingabe des Gerätepassworts (geheime PIN).
Häufig gestellte Fragen
Bouncy Castle (BKS) ist ein softwarebasierter KeyStore, der Schlüssel in einer passwortgeschützten Datei speichert. Android KeyStore verwendet Hardware-Isolierung TEE/StrongBox. BKS-Schlüssel können mit Root-Zugriff extrahiert werden, Android KeyStore-Schlüssel nicht. BKS eignet sich für CA-Zertifikate, Android KeyStore für private Schlüssel.
Ja, wenn Sie bei der Erzeugung PURPOSE_ENCRYPT oder PURPOSE_DECRYPT oder PURPOSE_SIGN oder PURPOSE_VERIFY angeben. Die beste Praxis ist jedoch, separate Schlüssel für verschiedene Operationen zu erstellen. Dies begrenzt den Schaden bei Kompromittierung eines Schlüssels und folgt dem Prinzip der geringsten Privilegien.
Verwenden Sie KeyStore.getKeyCharacteristics(alias), verfügbar über android.security.keystore. Die Methode gibt eine Reihe von Flags zurück: FLAG_HARDWARE — Schlüssel in TEE, FLAG_SECURE_ELEMENT — Schlüssel in StrongBox. Wenn keine Flags vorhanden sind, ist der Schlüssel rein softwarebasiert.
Alle Schlüssel, die mit setInvalidatedByBiometricEnrollment(true) erstellt wurden, werden von Keymaster automatisch ungültig gemacht. Bei Verwendungsversuch erhält die Anwendung KeyPermanentlyInvalidatedException. Mit diesen Schlüsseln verschlüsselte Daten gehen dauerhaft verloren.
Hardwareschlüssel (in TEE/StrongBox) unterstützen keine Sicherung — sie sind an ein bestimmtes Gerät gebunden. Softwarebasierte Schlüssel können in das Google Drive-Backup einbezogen werden. Zum Übertragen von Daten zwischen Geräten verschlüsseln Sie Daten auf dem Server und entschlüsseln Sie auf dem neuen Gerät.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch