Keystore (Android): co to jest, architektura i zasady działania

Autor: IT Sectr Opublikowano: 2026-03-14 Czas czytania: 10 min

Android Keystore — to systemowy mechanizm Androida do bezpiecznego przechowywania kluczy kryptograficznych w izolacji sprzętowej. System wykorzystuje Trusted Execution Environment (TEE) na urządzeniach z ARM TrustZone lub dedykowany Secure Element do ochrony kluczy na poziomie układu. Według Android Open Source Project, Keystore obsługuje algorytmy RSA, EC, AES i HMAC z generowaniem kluczy bezpośrednio w chronionym środowisku.

Najważniejsze

  • Android Keystore — dostawca KeyStore izolujący klucze kryptograficzne od przestrzeni użytkownika Androida
  • Klucze są generowane wewnątrz TEE lub Secure Element i nigdy nie opuszczają chronionego środowiska w jawnej postaci
  • Android 9+ dodaje KeyGenParameterSpec.Builder z parametrami: purpose, digest, padding, userAuthenticationRequired
  • Ochrona biometryczna kluczy wymaga potwierdzenia użytkownika przez BiometricPrompt przed każdą operacją
  • Keymaster HAL — sprzętowa warstwa abstrakcji realizująca operacje kryptograficzne w TEE lub Secure Element

Co to jest Android Keystore?

Android Keystore — to dostawca kryptograficzny (provider) zaimplementowany w Androidzie od API 1 (Android 1.0), ale pełne wsparcie sprzętowe pojawiło się od Androida 4.3 (API 18). Keystore rozwiązuje problem bezpiecznego przechowywania kluczy prywatnych w taki sposób, że nawet przy kompromitacji systemu operacyjnego atakujący nie może wyodrębnić kluczy w jawnej postaci.

Architektura KeyStore na Androidzie

Architektura Android Keystore składa się z trzech warstw: aplikacyjnego API (java.security.KeyStore), usługi systemowej (keystore daemon) i warstwy sprzętowej (Keymaster HAL). Aplikacja korzysta przez standardowe API Java Cryptography Architecture (JCA), a usługa systemowa kieruje żądania do Keymaster działającego w TEE.

Wszystkie operacje kryptograficzne z kluczami (podpis, deszyfrowanie) są wykonywane wewnątrz TEE lub Secure Element. Klucze nigdy nie opuszczają chronionego środowiska — aplikacja otrzymuje tylko uchwyt (alias) do odwoływania się do klucza. To fundamentalna różnica w porównaniu z programowymi KeyStore, gdzie klucze są potencjalnie dostępne w pamięci procesu.

Różnica od Java KeyStore

Standardowy JKS (Java KeyStore) lub BKS (Bouncy Castle) przechowują klucze w plikach chronionych hasłem. Android Keystore przechowuje klucze w izolacji sprzętowej, gdzie są chronione nawet przed rootem. JKS jest podatny na bezpośredni dostęp do systemu plików, Android Keystore — nie.

Inna różnica: w Android Keystore klucze mają ścisłe parametry użycia (purpose — tylko sign/verify/encrypt/decrypt), określone przy generacji. Nie można ich później zmienić, co zapobiega niewłaściwemu użyciu klucza.

Jak działa Android Keystore?

Podczas tworzenia nowego klucza aplikacja wywołuje KeyPairGenerator lub KeyGenerator z KeyGenParameterSpec, który zawiera wszystkie parametry przyszłego klucza. System przekazuje żądanie do Keymaster HAL, który generuje klucz wewnątrz TEE i zwraca uchwyt.

Proces generacji klucza

Metoda KeyGenParameterSpec.Builder przyjmuje obowiązkowe parametry: nazwę klucza w Keystore, przeznaczenie (PURPOSE_SIGN, PURPOSE_ENCRYPT), algorytm (RSA, EC, AES). Dodatkowo: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometria), keyValidityStart/End (ograniczenia czasowe).

Po ustawieniu parametrów KeyPairGenerator.generateKeyPair() zwraca KeyPair, gdzie PrivateKey to obiekt delegujący operacje do Keymaster. Klucz publiczny może być wyodrębniony, prywatny — nie. Istnieje tylko wewnątrz 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()
}

Podpisywanie i weryfikacja

Signature dla ECDSA lub RSA-PSS jest tworzone przez standardowe API: Signature.getInstance(algorithm).initSign(privateKey). Operacja podpisu jest wykonywana w TEE: aplikacja przekazuje dane, Keymaster podpisuje je sprzętowo i zwraca podpis. Klucz i dane nie mieszają się we wspólnej pamięci.

Dla ochrony biometrycznej konieczne jest przed podpisem uwierzytelnienie użytkownika przez BiometricPrompt. Bez udanego uwierzytelnienia Keymaster nie wykonuje operacji, zwracając 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 z CryptoObject(signature) żąda FaceID/PIN
}

Typy repozytoriów KeyStore

Android obsługuje dwa tryby przechowywania kluczy: programowy (na urządzeniach bez TEE) i sprzętowy (na urządzeniach z TEE lub Secure Element). Tryb zależy od możliwości SoC i wersji Androida.

Programowy KeyStore (software-only)

Na urządzeniach bez Trusted Execution Environment (przed Android 4.3 lub budżetowe SoC) klucze są przechowywane w zaszyfrowanej postaci przy użyciu klucza głównego pochodzącego z hasła ekranu blokady. Ten tryb jest mniej bezpieczny — klucze są dostępne w pamięci procesu podczas wykonywania operacji kryptograficznych.

Poziom ochrony opiera się na szyfrowaniu pliku KeyStore za pomocą AES-256-GCM. Klucz szyfrowania jest generowany na podstawie hasła użytkownika lub PIN-u przez Scrypt (PBKDF2 z dużą liczbą iteracji).

Sprzętowy KeyMaster (TEE/Secure Element)

Na nowoczesnych urządzeniach używany jest Keymaster 4.x w TEE (ARM TrustZone). Klucze są generowane, przechowywane i używane wyłącznie wewnątrz TrustZone. Nawet jądro Linuxa nie ma dostępu do kluczy prywatnych — tylko Keymaster HAL może wykonywać operacje.

Secure Element (np. eSE w Samsung Knox lub StrongBox w Google Pixel 3+) — to oddzielny układ z własnym procesorem i pamięcią. Jest certyfikowany Common Criteria EAL 4+ i zapewnia maksymalny poziom ochrony, w tym ochronę przed fizycznym otwarciem.

TypMiejsce przechowywaniaPoziom ochronyDostępne od API
SoftwarePlik /data/misc/keystoreŚredni (AES-256)API 1+
Keymaster 3TEE (TrustZone)WysokiAPI 23+
Keymaster 4TEE + Secure I/OBardzo wysokiAPI 28+
StrongBoxSprzętowy Secure ElementMaksymalnyAPI 28+, opcjonalnie

Praca z KeyStore API

Android Keystore jest zintegrowany z Java Cryptography Architecture (JCA). Do dostępu do dostawcy używa się standardowego KeyStore.getInstance("AndroidKeyStore"). API dostępne od API 18.

Tworzenie i ładowanie KeyStore

Metoda KeyStore.load(null) ładuje kontener KeyStore bieżącej aplikacji. Hasło nie jest wymagane — Android używa kontekstu aplikacji i jej UID do rozgraniczenia dostępu. Każda aplikacja widzi tylko swoje wpisy, chyba że używany jest wspólny UID.

Metody setEntry i getEntry działają z KeyStore.PrivateKeyEntry, SecretKeyEntry lub TrustedCertificateEntry. Parametr ProtectionParameter — zawsze null dla Android Keystore (ochrona zaimplementowana na poziomie systemu).

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)
}

Sprawdzanie typu repozytorium

Za pomocą KeyCharacteristics można określić, w jakim środowisku przechowywany jest klucz: programowym KeyStore, TEE lub StrongBox. Metoda getKeyCharacteristics() zwraca zestaw flag: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometria).

Algorytmy i bezpieczeństwo

Android Keystore obsługuje szeroki zestaw algorytmów kryptograficznych, podzielony na trzy kategorie: asymetryczne, symetryczne i MAC. Wsparcie dla konkretnych algorytmów zależy od wersji Keymaster HAL.

Obsługiwane algorytmy

RSA (1024–4096 bitów) — do podpisu (PKCS1, PSS) i szyfrowania (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — do podpisu ECDSA i uzgadniania ECDH. AES (128, 256 bitów) — do szyfrowania symetrycznego w trybach CBC, CTR, GCM. HMAC (SHA1, SHA256, SHA512) — do uwierzytelniania wiadomości.

Dla każdego klucza określa się setPurposes, ograniczający możliwe operacje. Klucz RSA z PURPOSE_SIGN nie może być użyty do szyfrowania, nawet jeśli atakujący ma dostęp do API. To wymuszanie użycia klucza na poziomie sprzętu.

Ochrona przed kompromitacją

Keymaster zawiera licznik nieudanych prób uwierzytelnienia biometrycznego. Po określonej liczbie nieudanych prób (konfigurowane przez setInvalidatedByBiometricEnrollment) klucz staje się niedostępny i wymaga usunięcia/regeneracji. Po usunięciu wszystkich szablonów biometrycznych wszystkie klucze z userAuthenticationRequired=true są automatycznie unieważniane.

Obsługiwana jest również Key Attestation (Android 8.1+): na żądanie aplikacji Keymaster podpisuje certyfikat z informacjami o charakterystykach klucza (sprzętowy/programowy, algorytm, purges). Serwer może zweryfikować ten certyfikat w celu potwierdzenia, że klucz został utworzony w zaufanym środowisku.

Często zadawane pytania

Jaka jest różnica między Android Keystore a KeyStore w Javie?

Java KeyStore przechowuje klucze w pliku chronionym hasłem (JKS, BKS). Android Keystore używa izolacji sprzętowej TEE lub Secure Element. Java KeyStore jest podatny przy dostępie root, Android Keystore — nie, ponieważ klucze prywatne nigdy nie opuszczają chronionego środowiska.

Czy można zaimportować istniejący klucz do Android Keystore?

Tak, przez KeyStore.setEntry z KeyProtection. Jednak zaimportowany klucz nie będzie miał ochrony sprzętowej — będzie przechowywany w programowym Keystore, zaszyfrowanym kluczem głównym. Dla maksymalnego bezpieczeństwa zawsze generuj klucze wewnątrz Keystore.

Jak sprawdzić, czy urządzenie obsługuje sprzętowy KeyStore?

Użyj KeyChain.isBoundKeyAlgorithm lub sprawdź KeyCharacteristics po wygenerowaniu klucza. Obecność FLAG_HARDWARE w charakterystykach oznacza, że klucz został utworzony w TEE. Można też sprawdzić android.security.keystore.isHardwareBacked().

Co dzieje się z kluczami po usunięciu aplikacji?

Po usunięciu aplikacji Android usuwa wszystkie jej klucze z Keystore. Dane są nieodwracalnie tracone. Przy ponownej instalacji aplikacja musi wygenerować nowe klucze. Kopia zapasowa kluczy przez TEE jest niemożliwa ze względów architektonicznych.

Jak KeyStore chroni przed atakami przez debugowanie?

Na zablokowanym urządzeniu Keymaster nie wykonuje żadnych operacji. Klucze z userAuthenticationRequired=true wymagają potwierdzenia biometrycznego za każdym razem. Nawet z dostępem root atakujący nie może wywołać Keymaster bezpośrednio — tylko przez Android Keystore service.

Podsumowanie

  • Android Keystore — dostawca kryptograficzny JCA z izolacją sprzętową kluczy przez TEE lub Secure Element
  • Klucze są generowane wewnątrz TrustZone i nigdy nie opuszczają chronionego środowiska w jawnej postaci
  • KeyGenParameterSpec określa parametry klucza: purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL realizuje trzy poziomy: programowy (software), TEE (Keymaster 3/4) i StrongBox (sprzętowy Secure Element)
  • Ochrona biometryczna kluczy jest zapewniana przez setUserAuthenticationRequired i BiometricPrompt z CryptoObject
  • Key Attestation (API 28+) pozwala zweryfikować na serwerze, że klucz został utworzony w środowisku sprzętowym
  • Używaj Android Keystore do przechowywania kluczy prywatnych podpisu, szyfrowania i uwierzytelniania w aplikacjach Android

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również