Android Keystore — ay isang mekanismo ng system ng Android para sa ligtas na pag-iimbak ng mga cryptographic key sa hardware isolation. Gumagamit ang system ng Trusted Execution Environment (TEE) sa mga device na may ARM TrustZone o dedikadong Secure Element para protektahan ang mga key sa antas ng chip. Ayon sa Android Open Source Project, sinusuportahan ng Keystore ang mga algorithm na RSA, EC, AES at HMAC na may pagbuo ng key nang direkta sa ligtas na kapaligiran.
Pangunahing
Android Keystore — ay isang cryptographic provider na ipinatupad sa Android mula API 1 (Android 1.0), ngunit ang buong hardware support ay lumitaw sa Android 4.3 (API 18). Nilulutas ng Keystore ang problema ng ligtas na pag-iimbak ng mga pribadong key sa paraang kahit na makompromiso ang operating system, hindi ma-extract ng attacker ang mga key sa bukas na anyo.
Ang arkitektura ng Android Keystore ay binubuo ng tatlong antas: application API (java.security.KeyStore), system service (keystore daemon) at hardware layer (Keymaster HAL). Ang application ay uma-access sa pamamagitan ng standard Java Cryptography Architecture (JCA) API, at ang system service ay nagruruta ng mga kahilingan sa Keymaster na tumatakbo sa TEE.
Lahat ng cryptographic na operasyon gamit ang mga key (pirma, decryption) ay isinasagawa sa loob ng TEE o Secure Element. Ang mga key ay hindi kailanman iniiwan ang ligtas na kapaligiran — ang application ay tumatanggap lamang ng isang alias upang sumangguni sa key. Ito ay isang pangunahing pagkakaiba mula sa software KeyStore, kung saan ang mga key ay potensyal na ma-access sa memorya ng proseso.
Ang standard na JKS (Java KeyStore) o BKS (Bouncy Castle) ay nag-iimbak ng mga key sa mga file na protektado ng password. Ang Android Keystore ay nag-iimbak ng mga key sa hardware isolation, kung saan protektado sila kahit mula sa root user. Ang JKS ay mahina sa direktang pag-access sa file system, ang Android Keystore — hindi.
Isa pang pagkakaiba: sa Android Keystore, ang mga key ay may mahigpit na mga parameter ng paggamit (purpose — sign/verify/encrypt/decrypt lamang) na itinakda sa pagbuo. Hindi sila mababago pagkatapos, na pumipigil sa maling paggamit ng key.
Sa paglikha ng isang bagong key, ang application ay tumatawag sa KeyPairGenerator o KeyGenerator na may KeyGenParameterSpec, na naglalaman ng lahat ng parameter ng hinaharap na key. Ipinapasa ng system ang kahilingan sa Keymaster HAL, na bumubuo ng key sa loob ng TEE at nagbabalik ng isang alias.
Ang pamamaraang KeyGenParameterSpec.Builder ay tumatanggap ng mga sapilitang parameter: pangalan ng key sa Keystore, layunin (PURPOSE_SIGN, PURPOSE_ENCRYPT), algorithm (RSA, EC, AES). Karagdagan: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometrics), keyValidityStart/End (mga limitasyon sa oras).
Pagkatapos itakda ang mga parameter, ang KeyPairGenerator.generateKeyPair() ay nagbabalik ng KeyPair, kung saan ang PrivateKey ay isang bagay na nagde-delegate ng mga operasyon sa Keymaster. Ang pampublikong key ay maaaring makuha, ang pribadong key — hindi. Ito ay umiiral lamang sa loob ng TEE.
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()
}
Ang Signature para sa ECDSA o RSA-PSS ay nilikha sa pamamagitan ng standard API: Signature.getInstance(algorithm).initSign(privateKey). Ang operasyon ng pagpirma ay isinasagawa sa TEE: ang application ay nagpapadala ng data, pinipirma ito ng Keymaster sa hardware at ibinabalik ang pirma. Ang key at data ay hindi naghahalo sa shared memory.
Para sa biometric na proteksyon, kinakailangan ang pag-authenticate ng user sa pamamagitan ng BiometricPrompt bago ang pagpirma. Kung walang matagumpay na pag-authenticate, hindi isinasagawa ng Keymaster ang operasyon, na nagbabalik ng CryptoAuthenticationException.
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 na may CryptoObject(signature) ay humihiling ng FaceID/PIN
}
Sinusuportahan ng Android ang dalawang mode ng pag-iimbak ng key: software (sa mga device na walang TEE) at hardware (sa mga device na may TEE o Secure Element). Ang mode ay depende sa mga kakayahan ng SoC at bersyon ng Android.
Sa mga device na walang Trusted Execution Environment (bago ang Android 4.3 o budget SoC) ang mga key ay naka-imbak sa naka-encrypt na form gamit ang isang master key na nagmula sa lock screen password. Ang mode na ito ay hindi gaanong secure — ang mga key ay naa-access sa memorya ng proseso sa panahon ng cryptographic operations.
Ang antas ng proteksyon ay batay sa pag-encrypt ng KeyStore file gamit ang AES-256-GCM. Ang encryption key ay nabuo batay sa password ng user o PIN sa pamamagitan ng Scrypt (PBKDF2 na may malaking bilang ng mga iteration).
Sa mga modernong device, ginagamit ang Keymaster 4.x sa TEE (ARM TrustZone). Ang mga key ay nabuo, naka-imbak at ginagamit nang eksklusibo sa loob ng TrustZone. Kahit na ang Linux kernel ay walang access sa mga pribadong key — tanging ang Keymaster HAL ang maaaring magsagawa ng mga operasyon.
Secure Element (hal. eSE sa Samsung Knox o StrongBox sa Google Pixel 3+) — ay isang hiwalay na chip na may sariling processor at memorya. Ito ay sertipikado ng Common Criteria EAL 4+ at nagbibigay ng maximum na antas ng proteksyon, kabilang ang proteksyon laban sa pisikal na pagbubukas.
| Uri | Lokasyon ng imbakan | Antas ng proteksyon | Magagamit mula API |
|---|---|---|---|
| Software | File /data/misc/keystore | Katamtaman (AES-256) | API 1+ |
| Keymaster 3 | TEE (TrustZone) | Mataas | API 23+ |
| Keymaster 4 | TEE + Secure I/O | Napakataas | API 28+ |
| StrongBox | Hardware Secure Element | Maximum | API 28+, opsyonal |
Ang Android Keystore ay isinama sa Java Cryptography Architecture (JCA). Para sa pag-access sa provider, ginagamit ang standard na KeyStore.getInstance("AndroidKeyStore"). Ang API ay magagamit mula API 18.
Ang pamamaraang KeyStore.load(null) ay naglo-load ng KeyStore container ng kasalukuyang application. Hindi kinakailangan ang password — ginagamit ng Android ang konteksto ng application at UID nito para sa pag-iba ng access. Ang bawat application ay nakikita lamang ang sarili nitong mga entry, maliban kung ginagamit ang shared UID.
Ang mga pamamaraang setEntry at getEntry ay gumagana sa KeyStore.PrivateKeyEntry, SecretKeyEntry o TrustedCertificateEntry. Ang parameter na ProtectionParameter ay palaging null para sa Android Keystore (ang proteksyon ay ipinatupad sa antas ng system).
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)
}
Gamit ang KeyCharacteristics matutukoy kung saang kapaligiran naka-imbak ang key: software KeyStore, TEE o StrongBox. Ang pamamaraang getKeyCharacteristics() ay nagbabalik ng set ng mga flag: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometrics).
Sinusuportahan ng Android Keystore ang isang malawak na hanay ng mga cryptographic algorithm, nahahati sa tatlong kategorya: asymmetric, simetric at MAC. Ang suporta para sa mga partikular na algorithm ay depende sa bersyon ng Keymaster HAL.
RSA (1024–4096 bit) — para sa pagpirma (PKCS1, PSS) at pag-encrypt (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — para sa ECDSA signature at ECDH key agreement. AES (128, 256 bit) — para sa simetric encryption sa CBC, CTR, GCM modes. HMAC (SHA1, SHA256, SHA512) — para sa pag-authenticate ng mensahe.
Para sa bawat key ay itinakda ang setPurposes, na naglilimita sa mga posibleng operasyon. Ang isang RSA key na may PURPOSE_SIGN ay hindi maaaring gamitin para sa pag-encrypt, kahit na ang attacker ay may access sa API. Ito ay pagpapatupad ng paggamit ng key sa antas ng hardware.
Ang Keymaster ay may kasamang counter ng mga nabigong pagtatangka ng biometric authentication. Pagkatapos ng itinakdang bilang ng mga nabigong pagtatangka (na-configure sa pamamagitan ng setInvalidatedByBiometricEnrollment) ang key ay nagiging hindi ma-access at nangangailangan ng pagtanggal/regeneration. Kapag tinanggal ang lahat ng biometric template, lahat ng key na may userAuthenticationRequired=true ay awtomatikong invalidated.
Sinusuportahan din ang Key Attestation (Android 8.1+): sa kahilingan ng application, pinipirma ng Keymaster ang isang sertipiko na may impormasyon tungkol sa mga katangian ng key (hardware/software, algorithm, purges). Maaaring i-verify ng server ang sertipikong ito upang kumpirmahin na ang key ay nilikha sa isang pinagkakatiwalaang kapaligiran.
Mga Madalas Itanong
Java KeyStore ay nag-iimbak ng mga key sa isang file na protektado ng password (JKS, BKS). Ang Android Keystore ay gumagamit ng hardware isolation ng TEE o Secure Element. Ang Java KeyStore ay mahina sa root access, ang Android Keystore — hindi, dahil ang mga pribadong key ay hindi kailanman umaalis sa ligtas na kapaligiran.
Oo, sa pamamagitan ng KeyStore.setEntry na may KeyProtection. Gayunpaman, ang na-import na key ay hindi magkakaroon ng hardware protection — ito ay maiimbak sa software Keystore, naka-encrypt ng master key. Para sa maximum na seguridad, palaging bumuo ng mga key sa loob ng Keystore.
Gamitin ang KeyChain.isBoundKeyAlgorithm o suriin ang KeyCharacteristics pagkatapos bumuo ng key. Ang pagkakaroon ng FLAG_HARDWARE sa mga katangian ay nangangahulugan na ang key ay nilikha sa TEE. Maaari mo ring suriin ang android.security.keystore.isHardwareBacked().
Sa pagtanggal ng app, tinatanggal ng Android ang lahat ng key nito mula sa Keystore. Ang data ay hindi mababawi na nawawala. Sa muling pag-install, ang app ay dapat bumuo ng mga bagong key. Ang backup ng mga key sa pamamagitan ng TEE ay imposible para sa mga kadahilanang arkitektura.
Sa isang naka-lock na device, ang Keymaster ay hindi nagsasagawa ng anumang operasyon. Ang mga key na may userAuthenticationRequired=true ay nangangailangan ng biometric confirmation sa bawat oras. Kahit na may root access, hindi direktang matawagan ng attacker ang Keymaster — sa pamamagitan lamang ng Android Keystore service.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din