Android Keystore — un furnizor criptografic care generează și stochează chei de criptare într-un mediu de execuție izolat (TEE), inaccesibil chiar și pentru sistemul de operare. Potrivit AOSP Security Documentation (2025), Keystore este utilizat în peste 80% din aplicațiile Android din top 100 Google Play pentru protejarea tokenurilor și criptarea datelor. Înțelegerea Android Keystore este esențială pentru stocarea sigură a cheilor pe Android.
Principalele
Android Keystore — o componentă de sistem a platformei Android care oferă API pentru generarea, stocarea și utilizarea cheilor criptografice într-un mediu protejat. Spre deosebire de bibliotecile criptografice software (Bouncy Castle, Conscrypt), Keystore garantează că cheile private nu părăsesc niciodată zona de execuție izolată.
Keystore a apărut în Android 4.3 (API 18) ca furnizor software cu suport RSA. Începând cu Android 6.0 (API 23), Keystore a primit suport hardware prin Keymaster Hardware Abstraction Layer (HAL), care delegă operațiile criptografice Trusted Execution Environment (TEE) pe dispozitive compatibile. Potrivit Android Compatibility Definition Document (2025), toate dispozitivele cu Android 9+ trebuie să suporte Keystore hardware prin TEE sau StrongBox.
Cheile în Keystore sunt identificate printr-un alias — un șir transmis la crearea sau încărcarea cheii. Keystore nu permite obținerea materialului brut al cheii: metodele getEncoded() returnează null pentru cheile create în Keystore. Aceasta este o diferență fundamentală față de cheile software — un atacator nu poate extrage cheia privată chiar și cu control complet asupra dispozitivului.
Keystore este integrat cu alte mecanisme de securitate Android: autentificare biometrică (BiometricPrompt), criptare la nivel de fișiere (File-Based Encryption) și funcții de verificare SafetyNet / Play Integrity. Cheile pot fi configurate pentru ștergere automată în anumite condiții: la eliminarea codului PIN, la adăugarea unei noi amprente sau la expirarea perioadei de valabilitate.
Arhitectura Android Keystore include trei niveluri de implementare care diferă prin gradul de protecție hardware. Nivelul depinde de capacitățile hardware ale dispozitivului.
TEE (Trusted Execution Environment) — o zonă izolată care funcționează paralel cu sistemul de operare principal pe același procesor. TEE utilizează tehnologia ARM TrustZone, care împarte nucleul fizic al procesorului în două părți virtuale: Normal World (Android) și Secure World (TEE). Codul din Secure World are acces la memorie și periferice inaccesibile din Normal World.
Când o aplicație apelează o operație criptografică prin Keystore, cererea este transmisă prin Keymaster HAL către TEE, unde operația este executată hardware. Rezultatul revine la aplicație, dar cheia privată rămâne în memoria protejată TEE. TEE este certificat conform GlobalPlatform TEE Protection Profile și este o cerință obligatorie pentru Android 9+ pe dispozitive cu procesoare care suportă TrustZone.
TEE suportă algoritmii AES/GCM (128, 256 biți), RSA (2048, 4096 biți), EC (P-256, P-384, P-521) și HMAC-SHA256. Performanța TEE este mai mică decât criptografia software (cu 20–40%), dar pentru operații tipice (semnare JWT, decriptare cheie de sesiune) întârzierea nu depășește 10–50 ms.
StrongBox — un cip de securitate dedicat, fizic separat de procesorul principal. Spre deosebire de TEE, care partajează timpul procesorului cu Android, StrongBox are propriul CPU, memorie RAM, Generator de Numere Aleatoare Adevărate (TRNG) și stocare protejată (One-Time Programmable memory). StrongBox este certificat Common Criteria EAL 4+ și Secure IC Protection Profile.
StrongBox este disponibil pe dispozitive cu Android 9+ în prezența unui cip corespunzător (de exemplu, Titan M pe Google Pixel, Knox pe Samsung Galaxy). Dezvoltatorul activează StrongBox prin flagul setIsStrongBoxBacked(true) în KeyGenParameterSpec. În lipsa suportului hardware, flagul este ignorat și Keystore comută la TEE.
Limitări StrongBox: suportă un set limitat de algoritmi (AES-256, EC P-256, HMAC-SHA256), coada de operații — cel mult una simultan, numărul de operații — limitat de resursele cipului. StrongBox nu este destinat scenariilor cu încărcare mare — utilizați TEE pentru operații frecvente și StrongBox doar pentru chei critice (chei master de criptare, chei de semnare).
Software-based Keystore — o implementare software utilizată pe dispozitive fără suport hardware TEE sau StrongBox. Cheile sunt stocate criptat în sistemul de fișiere, dar cheia privată poate fi temporar decriptată în memoria RAM. Keystore software este mai puțin sigur — un atacator cu acces root poate intercepta cheia în memorie.
Începând cu Android 12 (API 31), Google cere suport hardware Keystore pentru toate dispozitivele noi. Dispozitivele cu Android 9–11 pot avea Keystore software pe modelele bugetare. Dezvoltatorul poate verifica nivelul de protecție prin KeyStore.getKeyCharacteristics() — atributul SECURITY_LEVEL_TRUSTED_ENVIRONMENT sau SECURITY_LEVEL_STRONGBOX confirmă protecția hardware.
Android Keystore suportă o gamă largă de algoritmi criptografici împărțiți pe categorii în funcție de tipul cheii. Alegerea algoritmului influențează performanța, compatibilitatea și nivelul de securitate.
AES (Advanced Encryption Standard) — criptare simetrică pentru protejarea datelor pe dispozitiv. Modul recomandat: AES/GCM/NoPadding (256 biți). GCM asigură criptare autentificată (AEAD) — verificarea integrității datelor criptate. Dimensiune IV (Vector de Inițializare): 12 octeți pentru GCM. Nu utilizați AES/ECB — nu asigură protecție adecvată.
RSA (Rivest–Shamir–Adleman) — criptare asimetrică pentru protejarea cheilor de sesiune și semnătura digitală. Dimensiune recomandată: 2048 sau 4096 biți. Moduri: RSA/ECB/PKCS1Padding (criptare) și RSA/ECB/PKCS1Sign (semnare). RSA 1024 este considerat învechit și nu este recomandat pentru aplicații noi (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — criptografie asimetrică pe curbe eliptice pentru semnare și schimb de chei. Curbe suportate: secp256r1 (P-256, obligatorie), secp384r1 (P-384) și secp521r1 (P-521). EC oferă securitate comparabilă cu RSA la o dimensiune semnificativ mai mică a cheii. P-256 este recomandată pentru majoritatea scenariilor: este suportată de toate dispozitivele și asigură un nivel de securitate de 128 de biți.
HMAC (Hash-based Message Authentication Code) — autentificare simetrică a mesajelor. Funcții hash suportate: SHA-256, SHA-384, SHA-512. HMAC este utilizat pentru verificarea integrității și autenticității datelor, de exemplu, pentru verificarea cererilor webhook sau verificarea integrității configurației.
Toți algoritmii pot fi legați de autentificarea biometrică prin KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). Pe Android 11+ este disponibil flagul setUserAuthenticationParameters() cu specificarea unui timeout (în secunde) în care cheia este disponibilă după autentificarea biometrică, fără o nouă solicitare.
Să analizăm exemple practice de lucru cu Android Keystore în Kotlin: generarea unei chei AES, criptarea datelor și crearea unei perechi asimetrice pentru semnare.
Exemplul creează o cheie AES/GCM de 256 de biți cu legătură la autentificarea biometrică. Cheia nu este disponibilă pentru export prin 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()
}
Exemplul criptează date utilizând o cheie din Android Keystore. Cipher obține cheia după alias, inițializează criptarea AES/GCM și returnează datele criptate împreună cu 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 + date criptate
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)
}
Exemplul creează o pereche de chei RSA-2048 în Keystore cu legătură la StrongBox. Cheia privată este utilizată pentru semnare, cheia publică poate fi exportată prin 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()
// Cheia publică poate fi exportată
val publicKey = pair.public // X509EncodedKeySpec
}
Utilizarea eficientă a Android Keystore necesită respectarea regulilor care asigură protecție maximă cu păstrarea performanței.
Utilizați KeyGenParameterSpec cu parametrii minim necesari: specificați doar acele purpose, block modes și paddings care sunt efectiv utilizate. Parametrii în exces (de exemplu, PURPOSE_ENCRYPT pentru o cheie utilizată doar pentru semnare) creează vectori de atac suplimentari. Android recomandă specificarea explicită a digest-ului pentru semnare — SHA256 este nivelul minim acceptabil (SHA1 este învechit).
Legati cheile de biometrie pentru operații critice: setUserAuthenticationRequired(true) garantează că cheia poate fi utilizată doar după autentificare biometrică. Pe Android 11+ utilizați setUserAuthenticationParameters() cu un timeout (recomandat 30–60 de secunde) pentru a nu solicita biometria la fiecare operație în cadrul aceleiași sesiuni. setInvalidatedByBiometricEnrollment(true) șterge automat cheia la adăugarea unei noi amprente sau fețe — aceasta previne accesul cu date biometrice vechi.
Verificați nivelul de securitate la etapa de inițializare: utilizați KeyStore.getKeyCharacteristics() pentru a determina SECURITY_LEVEL. Dacă dispozitivul suportă doar Keystore software (SECURITY_LEVEL_SOFTWARE), luați o decizie: fie renunțați la funcționalitate, fie utilizați criptare suplimentară (de exemplu, îmbrăcarea cheii cu parola utilizatorului). Nu vă bazați pe StrongBox dacă nu este garantat — specificați întotdeauna flagul setIsStrongBoxBacked(true) și verificați rezultatul prin getKeyCharacteristics.
Actualizați cheile conform programului: cheile criptografice au o durată de viață recomandată. NIST SP 800-57 recomandă schimbarea cheilor AES la fiecare 1–2 ani, a perechilor RSA/EC la fiecare 2–3 ani. Implementați un mecanism de rotație a cheilor: la pornirea aplicației verificați data creării cheii (KeyGenParameterSpec.Builder.setKeyValidityStart/End) și generați o cheie nouă la expirare. Datele vechi criptate cu cheia veche trebuie decriptate și re-criptate cu cea nouă.
Nu utilizați Keystore pentru date mari: Keystore este destinat stocării cheilor (câteva sute de octeți), nu pentru criptarea fișierelor mari. Pentru criptarea datelor utilizați schema: generați o cheie AES aleatoare (DEK — Data Encryption Key), criptați datele cu această cheie, iar DEK îl criptați cu cheia Keystore (KEK — Key Encryption Key). Android EncryptedSharedPreferences utilizează exact această schemă: cheia master în Keystore, datele — AES-256 GCM.
Întrebări frecvente
Nu, Android Keystore este proiectat astfel încât cheia privată să nu părăsească niciodată TEE sau StrongBox. Metoda getEncoded() returnează null pentru cheile create în Keystore. Cheia poate fi utilizată doar prin Cipher, Signature sau Mac API — materialul brut este indisponibil.
TEE (TrustZone) — izolare virtuală pe același procesor, utilizează partajarea timpului. StrongBox — un cip separat cu propriul CPU și memorie. StrongBox este mai sigur (Common Criteria EAL 4+), dar mai lent și suportă mai puțini algoritmi. TEE este potrivit pentru operații frecvente, StrongBox — pentru chei critice.
Utilizați KeyStore.getKeyCharacteristics() după generarea cheii cu flagul setIsStrongBoxBacked(true). Atributul SECURITY_LEVEL_STRONGBOX confirmă suportul hardware. Dacă dispozitivul nu suportă StrongBox, Keystore comută la TEE fără eroare — trebuie să verificați explicit nivelul de securitate.
Cheile în Keystore sunt șterse automat la ștergerea aplicației de pe dispozitiv. Pe Android 10+, cheile se pot păstra dacă aplicația are flagul allowBackup=true în manifest, dar vor fi inaccesibile după reinstallare. Se recomandă generarea cheilor din nou la o instalare curată.
Nu, Android Keystore este legat de hardware-ul unui anumit dispozitiv. O cheie generată în TEE al unui dispozitiv nu poate fi transferată pe altul. Pentru criptare cross-platformă utilizați schema: Keystore protejează cheia pe dispozitiv, iar cheile de sesiune sunt transmise printr-un API securizat cu criptare asimetrică.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și