KeyStore (Android) — bu apparat izolyatsiyasi imkoniyati bilan kalitlarni xavfsiz saqlash uchun Android-ga integratsiyalangan Java Cryptography Architecture (JCA) kriptografik provayderining amalga oshirilishidir. Android 4.3 (API 18) dan boshlab KeyStore Keymaster HAL orqali apparat kalitlarini qo'llab-quvvatlaydi, Android 9 (API 28) dan esa ajratilgan Secure Element-dagi kalitlar uchun StrongBox Keymaster-ni qo'llab-quvvatlaydi. Android Security Documentation ga ko'ra, “AndroidKeyStore” provayderi standart Bouncy Castle yoki OpenSSL KeyStore o'rnini bosadi va kalitlarning ruxsatsiz chiqarilishidan tizim himoyasini ta'minlaydi.
Asosiy fikrlar
Android-da KeyStore — bu alohida ilova yoki fayl emas, balki java.security.KeyStore interfeysini amalga oshiradigan kriptografik provayderdir. U shaxsiy kalitlar, simmetrik kalitlar va ishonchli markazlar (CA) sertifikatlarini saqlash va ishlatish uchun yagona API-ni ta'minlaydi. Provayder “AndroidKeyStore” nomi bilan ro'yxatdan o'tgan va standart KeyStore.getInstance() orqali mavjud.
Android 4.3 dan oldin kriptografik operatsiyalar Bouncy Castle orqali dasturiy ravishda bajarilar edi. Android 4.3 bilan ARM TrustZone-da TEE dan foydalanishga imkon beruvchi Keymaster HAL 1.0 paydo bo'ldi. Android 6.0 (API 23) barmoq izi bilan apparat autentifikatsiyasini qo'llab-quvvatlovchi Keymaster 2.0 ni qo'shdi. Android 9 (API 28) Keymaster 4.0 va ajratilgan Secure Element uchun StrongBox Keymaster-ni taqdim etdi.
Keymaster-ning har bir versiyasi yangi imkoniyatlar qo'shadi va kalitlar izolyatsiyasini yaxshilaydi. Zamonaviy qurilmalar (2022+) Google Mobile Services sertifikatsiyasi uchun Keymaster 4.0-ni qo'llab-quvvatlashi kerak, bu barcha Android ilovalari uchun TEE mavjudligini kafolatlaydi.
Android KeyStore uch darajadan iborat: Java API (KeyStore, KeyPairGenerator), tizim jarayoni keystore (C++, system service sifatida ishlaydi) va Keymaster HAL (TEE yoki Secure Element-dagi kutubxona). Ilova API-ni chaqiradi, keystore xizmati so'rovni Keymaster-ga yo'naltiradi, operatsiya himoyalangan muhitda bajariladi.
Barcha shaxsiy kalitlar TEE-da saqlanadi va foydalanuvchi makonidan o'qib bo'lmaydi. Hatto tizim keystore xizmati ham xom kalitlarga kirish imkoniga ega emas — faqat Keymaster ichidagi kalitlarga ishora qiluvchi tutqichlarga.
Android KeyStore JCA xizmat ko'rsatuvchi provayderining standart interfeysini amalga oshiradi. Ilova Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”) ni chaqirganda, Android Security Provider operatsiyani zanjir orqali Keymaster-ga topshiradi: Java → JNI → keystore service → Keymaster HAL.
AndroidKeyStore provayderi jarayon ishga tushganda avtomatik ro'yxatdan o'tadi. Uning ustuvorligi Bouncy Castle yoki Conscrypt-dan yuqori. Shuning uchun KeyStore.getInstance() provaydersiz chaqirilganda, ko'p hollarda AndroidKeyStore qaytariladi. Aniq chaqirish uchun KeyStore.getInstance(“AndroidKeyStore”) dan foydalaning.
Har bir Android ilovasi KeyStore-da izolyatsiya qilingan konteynerga ega. Bir xil UID (shared userId) ga ega ilovalar ma'lum kalitlarga umumiy kirishga ega bo'lishi mumkin, ammo standart o'rnatish ilova A ilova B ning kalitlarini o'qiy olmasligini kafolatlaydi.
load(null) — KeyStore-ni ishga tushirish. Parametr AndroidKeyStore uchun har doim null. setEntry — kalitni KeyProtection (purposes, digest, padding) bilan saqlash. getEntry — KeyStore.PrivateKeyEntry, SecretKeyEntry yoki TrustedCertificateEntry olish. containsAlias — kalit mavjudligini tekshirish. deleteEntry — kalitni o'chirish (qaytarib bo'lmaydigan).
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 qurilmadagi Keymaster HAL versiyasiga qarab o'zgaruvchan keng kriptografik algoritmlar to'plamini qo'llab-quvvatlaydi. Ishlab chiquvchi yaratish vaqtida KeyGenParameterSpec.Builder orqali qo'llab-quvvatlanadigan algoritmlar ro'yxatini olishi mumkin — mos kelmaydigan parametrlar InvalidAlgorithmParameterException ni keltirib chiqaradi.
RSA (1024–4096 bit) — imzo (SHA-1/SHA-256/SHA-384/SHA-512 bilan PKCS1, PSS) va shifrlash (SHA-1/SHA-256 bilan OAEP) uchun. EC (P-224, P-256, P-384, P-521) — ECDSA imzosi va ECDH kalit kelishuvi uchun. X25519 va Ed25519 — Android 12 (API 31) dan zamonaviy kriptografik protokollar uchun.
Asimmetrik kalitlar uchun Har doim Keymaster ichida yarating, shaxsiy kalitlarni HECH QACHON import qilmang. Import qilingan shaxsiy kalitlar apparat himoyasiga ega emas — ular dasturiy qatlamda saqlanadi va AP buzilishida zaifdir.
AES (128, 256 bit) — CBC, CTR, GCM rejimlarida simmetrik shifrlash uchun. HMAC (SHA-1, SHA-256, SHA-512) — xabarlarni autentifikatsiya qilish uchun. ChaCha20 (Android 12+) — Poly1305 autentifikatsiyasi bilan yuqori unumli oqimli shifrlash uchun.
| Algoritm | Keymaster | Maqsad | API |
|---|---|---|---|
| RSA | KM 1.0+ | Imzo, shifrlash | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Simmetrik shifrlash | 23+ |
| HMAC | KM 2.0+ | Autentifikatsiya kodi | 23+ |
| ChaCha20 | KM 3.0+ | Oqimli shifrlash | 31+ |
| X25519/E25519 | KM 3.0+ | Kalit almashinuvi | 31+ |
KeyStore.PrivateKeyEntry — shaxsiy kalit (eksport qilib bo'lmaydigan) va sertifikat zanjirini o'z ichiga oladi. KeyStore.SecretKeyEntry — simmetrik kalitlar uchun. KeyStore.TrustedCertificateEntry — ishonchli CA sertifikatlari uchun. Ochiq kalitlar keyStore.getCertificate(alias).publicKey orqali eksport uchun mavjud.
To'liq stsenariyni ko'rib chiqaylik: ma'lumotlarni shifrlash uchun AES kalitini yaratish va biometrik himoya bilan imzo uchun EC kalitini yaratish. Ikkala kalit ham apparat qo'llab-quvvatlovi bilan Android KeyStore ichida yaratiladi.
AES kaliti KeyGenParameterSpec bilan KeyGenerator orqali yaratiladi. Parametrlar: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (autentifikatsiyali tavsiya etilgan rejim), ENCRYPTION_PADDING_NONE (GCM uchun padding kerak emas).
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)
}
EC kaliti userAuthenticationRequired=true bilan har bir imzo operatsiyasidan oldin foydalanuvchi autentifikatsiyasini talab qiladi. Buning uchun Signature obyektini o'z ichiga olgan CryptoObject bilan BiometricPrompt ishlatiladi. Muvaffaqiyatli biometriyadan so'ng Keymaster operatsiyaga ruxsat beradi.
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 dasturiy KeyStore-lar (JKS, BKS) ta'minlay olmaydigan apparat xavfsizlik kafolatlarini beradi. Kalitlar SoC darajasida himoyalangan va Android foydalanuvchi makoni ustidan to'liq nazorat ham shaxsiy kalitni chiqarishga imkon bermaydi.
Key Attestation — ilova (va server) ga kalit qanday muhitda yaratilganligini tekshirishga imkon beruvchi mexanizm. Android Keystore kalitning xususiyatlari ro'yxatini o'z ichiga olgan sertifikatni imzolaydi: algoritm, o'lcham, purges, hardware-backed (True/False), origin (GENERATED, IMPORTED). Server sertifikatlar zanjirini Google ildiz sertifikatigacha tekshiradi.
Bu moliyaviy ilovalar uchun juda muhim: server kalitning apparat muhitida yaratilishini talab qilishi mumkin (Hardware-Backed = True) va dasturiy Keystore-da yaratilgan kalitlarni rad etishi mumkin. Key Attestation tajovuzkor Keystore-ni emulyator bilan almashtiradigan hujumlarning oldini oladi.
setInvalidatedByBiometricEnrollment(true) foydalanuvchining biometrik shablonlari o'zgartirilganda yoki o'chirilganda kalit Keymaster tomonidan avtomatik o'chirilishini anglatadi. Bu tajovuzkor mavjud hisobga o'z barmoq izini qo'shadigan hujumlardan himoyadir. Yangi barmoq izi qo'shilgandan so'ng, eski kalitlar mavjud bo'lmaydi.
Muvaffaqiyatsiz biometrik autentifikatsiya urinishlari hisoblagichi ham Keymaster tomonidan boshqariladi. maxBiometricAttempt dan so'ng (ishlab chiqaruvchi tomonidan sozlanadi, odatda 5) Keymaster biometrik kalitlar bilan barcha operatsiyalarni 30 soniyaga bloklaydi. 10 muvaffaqiyatsiz urinishdan so'ng — qurilma paroli (maxfiy PIN) kiritilgunga qadar.
Tez-tez beriladigan savollar
Bouncy Castle (BKS) — kalitlarni parol bilan himoyalangan faylda saqlaydigan dasturiy KeyStore. Android KeyStore TEE/StrongBox apparat izolyatsiyasidan foydalanadi. BKS kalitlarini root kirishi bilan chiqarib olish mumkin, Android KeyStore kalitlarini esa yo'q. BKS CA sertifikatlari uchun, Android KeyStore esa shaxsiy kalitlar uchun mos keladi.
Ha, agar yaratish vaqtida PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY ko'rsatilgan bo'lsa. Biroq, eng yaxshi amaliyot turli operatsiyalar uchun alohida kalitlar yaratishdir. Bu kalitlardan birining buzilishida zararni cheklaydi va eng kam imtiyoz prinsipiga mos keladi.
android.security.keystore orqali mavjud bo'lgan KeyStore.getKeyCharacteristics(alias) dan foydalaning. Metod bayroqlar to'plamini qaytaradi: FLAG_HARDWARE — kalit TEE-da, FLAG_SECURE_ELEMENT — kalit StrongBox-da. Bayroqlar bo'lmasa — kalit dasturiy.
setInvalidatedByBiometricEnrollment(true) bilan yaratilgan barcha kalitlar Keymaster tomonidan avtomatik bekor qilinadi. Foydalanishga urinishda ilova KeyPermanentlyInvalidatedException oladi. Ushbu kalitlar bilan shifrlangan ma'lumotlar qaytarib bo'lmaydigan darajada yo'qoladi.
Apparat kalitlari (TEE/StrongBox-da) zaxira nusxani qo'llab-quvvatlamaydi — ular ma'lum qurilmaga bog'langan. Dasturiy kalitlar Google Drive zaxira nusxasiga kiritilishi mumkin. Qurilmalar o'rtasida ma'lumotlarni ko'chirish uchun ma'lumotlarni serverda shifrlang va yangi qurilmada shifrni oching.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.