Android Keystore — kriptoqrafik açarların aparat izolyasiyasında təhlükəsiz saxlanması üçün Android-in sistem mexanizmidir. Sistem ARM TrustZone ilə cihazlarda Trusted Execution Environment (TEE) və ya çip səviyyəsində açarları qorumaq üçün ayrılmış Secure Element istifadə edir. Android Open Source Project-ə görə, Keystore açarların birbaşa qorunan mühitdə yaradılması ilə RSA, EC, AES və HMAC alqoritmlərini dəstəkləyir.
Başlıca
Android Keystore — Android-də API 1-dən (Android 1.0) etibarən tətbiq edilmiş kriptoqrafik təminatçıdır (provider), lakin tam aparat dəstəyi Android 4.3-dən (API 18) başlayır. Keystore şəxsi açarları elə təhlükəsiz şəkildə saxlamaq problemini həll edir ki, əməliyyat sistemi kompromatasiya olunsa belə, hücumçu açarları açıq şəkildə çıxara bilməz.
Android Keystore arxitekturası üç səviyyədən ibarətdir: tətbiqi API (java.security.KeyStore), sistem xidməti (keystore daemon) və aparat səviyyəsi (Keymaster HAL). Tətbiq standart Java Cryptography Architecture (JCA) API vasitəsilə müraciət edir, sistem xidməti isə sorğuları TEE-də işləyən Keymaster-ə yönləndirir.
Açarlarla bütün kriptoqrafik əməliyyatlar (imza, şifrənin açılması) TEE və ya Secure Element daxilində yerinə yetirilir. Açarlar heç vaxt qorunan mühiti tərk etmir — tətbiq açara müraciət etmək üçün yalnız identifikator (alias) alır. Bu, açarların potensial olaraq proses yaddaşında əlçatan olduğu proqram KeyStore-dan fundamental fərqdir.
Standart JKS (Java KeyStore) və ya BKS (Bouncy Castle) açarları şifrə ilə qorunan fayllarda saxlayır. Android Keystore açarları aparat izolyasiyasında saxlayır, burada onlar hətta root istifadəçisindən də qorunur. JKS fayl sisteminə birbaşa çıxışda həssasdır, Android Keystore — yox.
Digər fərq: Android Keystore-da açarlar yaradılarkən müəyyən edilmiş ciddi istifadə parametrlərinə (purpose — yalnız sign/verify/encrypt/decrypt) malikdir. Onları sonradan dəyişdirmək olmaz, bu da açarın səhv istifadəsinin qarşısını alır.
Yeni açar yaradılarkən tətbiq gələcək açarın bütün parametrlərini ehtiva edən KeyPairGenerator və ya KeyGenerator-u KeyGenParameterSpec ilə çağırır. Sistem sorğunu Keymaster HAL-ə ötürür, o da açarı TEE daxilində yaradır və identifikator qaytarır.
KeyGenParameterSpec.Builder metodu məcburi parametrləri qəbul edir: Keystore-da açar adı, təyinat (PURPOSE_SIGN, PURPOSE_ENCRYPT), alqoritm (RSA, EC, AES). Əlavə olaraq: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometriya), keyValidityStart/End (vaxt məhdudiyyətləri).
Parametrlər təyin edildikdən sonra KeyPairGenerator.generateKeyPair() KeyPair qaytarır, burada PrivateKey əməliyyatları Keymaster-ə həvalə edən obyektdir. Açıq açar çıxarıla bilər, şəxsi açar — yox. O, yalnız TEE daxilində mövcuddur.
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()
}
ECDSA və ya RSA-PSS üçün Signature standart API vasitəsilə yaradılır: Signature.getInstance(algorithm).initSign(privateKey). İmzalama əməliyyatı TEE-də yerinə yetirilir: tətbiq məlumatları ötürür, Keymaster onları aparat vasitəsilə imzalayır və imzanı qaytarır. Açar və məlumatlar ümumi yaddaşda qarışmır.
Biometrik qorunma üçün imzalamadan əvvəl BiometricPrompt vasitəsilə istifadəçinin doğrulanması tələb olunur. Uğurlu doğrulama olmadan Keymaster əməliyyatı yerinə yetirmir, CryptoAuthenticationException qaytarır.
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 CryptoObject(signature) ilə FaceID/PIN tələb edir
}
Android açarların saxlanması üçün iki rejimi dəstəkləyir: proqram (TEE olmayan cihazlarda) və aparat (TEE və ya Secure Element olan cihazlarda). Rejim SoC imkanlarından və Android versiyasından asılıdır.
Trusted Execution Environment olmayan cihazlarda (Android 4.3-ə qədər və ya büdcə SoC) açarlar bloklanma ekranı şifrəsindən əldə edilmiş master açardan istifadə edərək şifrələnmiş formada saxlanılır. Bu rejim daha az təhlükəsizdir — kriptoqrafik əməliyyatlar zamanı açarlar proses yaddaşında əlçatandır.
Qorunma səviyyəsi AES-256-GCM istifadə edərək KeyStore faylının şifrələnməsinə əsaslanır. Şifrələmə açarı Scrypt (böyük sayda iterasiya ilə PBKDF2) vasitəsilə istifadəçi şifrəsi və ya PIN əsasında yaradılır.
Müasir cihazlarda TEE-də (ARM TrustZone) Keymaster 4.x istifadə olunur. Açarlar yalnız TrustZone daxilində yaradılır, saxlanılır və istifadə olunur. Hətta Linux növəsinin şəxsi açarlara çıxışı yoxdur — yalnız Keymaster HAL əməliyyatları yerinə yetirə bilər.
Secure Element (məsələn, Samsung Knox-da eSE və ya Google Pixel 3+-da StrongBox) — öz prosessoru və yaddaşı olan ayrıca çipdir. Common Criteria EAL 4+ sertifikatına malikdir və fiziki açılış da daxil olmaqla maksimum qorunma səviyyəsini təmin edir.
| Növ | Saxlama yeri | Qorunma səviyyəsi | API-dən etibarən |
|---|---|---|---|
| Software | Fayl /data/misc/keystore | Orta (AES-256) | API 1+ |
| Keymaster 3 | TEE (TrustZone) | Yüksək | API 23+ |
| Keymaster 4 | TEE + Secure I/O | Çox yüksək | API 28+ |
| StrongBox | Aparat Secure Element | Maksimum | API 28+, isteğə bağlı |
Android Keystore Java Cryptography Architecture (JCA) ilə inteqrasiya edilmişdir. Təminatçıya çıxış üçün standart KeyStore.getInstance("AndroidKeyStore") istifadə olunur. API API 18-dən etibarən mövcuddur.
KeyStore.load(null) metodu cari tətbiqin KeyStore konteynerini yükləyir. Şifrə tələb olunmur — Android çıxışı ayırmaq üçün tətbiq kontekstindən və onun UID-sindən istifadə edir. Hər tətbiq ortaq UID istifadə edilməyibsə, yalnız öz qeydlərini görür.
setEntry və getEntry metodları KeyStore.PrivateKeyEntry, SecretKeyEntry və ya TrustedCertificateEntry ilə işləyir. ProtectionParameter parametri Android Keystore üçün həmişə null-dur (qorunma sistem səviyyəsində həyata keçirilir).
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)
}
KeyCharacteristics vasitəsilə açarın hansı mühitdə saxlandığını müyəyyən etmək olar: proqram KeyStore, TEE və ya StrongBox. getKeyCharacteristics() metodu bayraqlar toplusunu qaytarır: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometriya).
Android Keystore üç kateqoriyaya bölünmüş geniş kriptoqrafik alqoritmlər dəstini dəstəkləyir: asimmetrik, simmetrik və MAC. Konkret alqoritmlərin dəstəyi Keymaster HAL versiyasından asılıdır.
RSA (1024–4096 bit) — imza (PKCS1, PSS) və şifrələmə (OAEP, PKCS1) üçün. EC (P-224, P-256, P-384, P-521) — ECDSA imzası və ECDH razılaşdırması üçün. AES (128, 256 bit) — CBC, CTR, GCM rejimlərində simmetrik şifrələmə üçün. HMAC (SHA1, SHA256, SHA512) — mesaj doğrulaması üçün.
Hər açar üçün mümkün əməliyyatları məhdudlaşdıran setPurposes təyin edilir. PURPOSE_SIGN olan RSA açarı, hətta hücumçunun API-ə çıxışı olsa belə, şifrələmə üçün istifadə edilə bilməz. Bu, aparat səviyyəsində açar istifadəsinin məcburiyyətidir.
Keymaster uğursuz biometrik doğrulama cəhdlərinin sayını izləyir. Müəyyən sayda uğursuz cəhddən sonra (setInvalidatedByBiometricEnrollment vasitəsilə konfiqurasiya olunur) açar əlçatmaz olur və silinmə/yenidən yaradılma tələb edir. Bütün biometrik şablonlar silindikdə, userAuthenticationRequired=true olan bütün açarlar avtomatik olaraq etibarsız edilir.
Həmçinin Key Attestation (Android 8.1+) dəstəklənir: tətbiqin sorğusuna əsasən Keymaster açarın xarakteristikaları (aparat/proqram, alqoritm, purges) haqqında məlumatı olan sertifikat imzalayır. Server açarın etibarlı mühitdə yaradıldığını təsdiqləmək üçün bu sertifikatı yoxlaya bilər.
Tez-tez verilən suallar
Java KeyStore açarları şifrə ilə qorunan faylda (JKS, BKS) saxlayır. Android Keystore TEE və ya Secure Element aparat izolyasiyasından istifadə edir. Java KeyStore root çıxışında həssasdır, Android Keystore — yox, çünki şəxsi açarlar heç vaxt qorunan mühiti tərk etmir.
Bəli, KeyStore.setEntry vasitəsilə KeyProtection ilə. Lakin idxal edilmiş açar aparat qorunmasına malik olmayacaq — o, master açarla şifrələnmiş proqram Keystore-da saxlanılacaq. Maksimum təhlükəsizlik üçün həmişə açarları Keystore daxilində yaradın.
KeyChain.isBoundKeyAlgorithm istifadə edin və ya açar yaradıldıqdan sonra KeyCharacteristics yoxlayın. Xarakteristikalarda FLAG_HARDWARE olması açarın TEE-də yaradıldığı anlamına gəlir. Həmçinin android.security.keystore.isHardwareBacked() yoxlana bilər.
Tətbiq silindikdə Android onun bütün açarlarını Keystore-dan silir. Məlumatlar geri qaytarılmaz şəkildə itir. Yenidən quraşdırmada tətbiq yeni açarlar yaratmalıdır. TEE vasitəsilə açarların ehtiyat surətinin yaradılması memarlıq səbəblərinə görə mümkün deyil.
Bloklanmış cihazda Keymaster heç bir əməliyyat yerinə yetirmir. userAuthenticationRequired=true olan açarlar hər dəfə biometrik təsdiq tələb edir. Hətta root çıxışı ilə belə hücumçu Keymaster-ə birbaşa zəng edə bilməz — yalnız Android Keystore service vasitəsilə.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun