KeyStore (Android) — är en implementering av den kryptografiska leverantören Java Cryptography Architecture (JCA) integrerad i Android för säker nyckellagring med möjlighet till hårdvaruisolering. Från och med Android 4.3 (API 18) stödjer KeyStore hårdvarunycklar via Keymaster HAL, och från Android 9 (API 28) — StrongBox Keymaster för nycklar i dedikerat Secure Element. Enligt Android Security Documentation ersätter leverantören “AndroidKeyStore” standard Bouncy Castle eller OpenSSL KeyStore, vilket ger systemomfattande skydd mot obehörig extraktion av nycklar.
Huvudpunkter
KeyStore i Android — är ingen separat applikation eller fil, utan en kryptografisk leverantör som implementerar gränssnittet java.security.KeyStore. Den tillhandahåller ett enhetligt API för lagring och användning av privata nycklar, symmetriska nycklar och certifikat från betrodda certifikatutfärdare (CA). Leverantören är registrerad under namnet “AndroidKeyStore” och är tillgänglig via standard KeyStore.getInstance().
Före Android 4.3 utfördes kryptografiska operationer programvarumässigt via Bouncy Castle. Med Android 4.3 kom Keymaster HAL 1.0, vilket möjliggjorde användning av TEE på ARM TrustZone. Android 6.0 (API 23) lade till Keymaster 2.0 med stöd för hårdvaruautentisering med fingeravtryck. Android 9 (API 28) introducerade Keymaster 4.0 och StrongBox Keymaster för dedikerat Secure Element.
Varje version av Keymaster lägger till nya funktioner och förbättrar isoleringen av nycklar. Moderna enheter (2022+) måste stödja Keymaster 4.0 för certifiering av Google Mobile Services, vilket garanterar närvaro av TEE för alla Android-applikationer.
Android KeyStore består av tre nivåer: Java API (KeyStore, KeyPairGenerator), systemprocessen keystore (C++, fungerar som system service) och Keymaster HAL (bibliotek i TEE eller Secure Element). Applikationen anropar API:et, keystore-tjänsten dirigerar begäran till Keymaster och operationen utförs i den skyddade miljön.
Alla privata nycklar lagras i TEE och kan inte läsas från användarutrymmet. Även systemets keystore-tjänst har inte åtkomst till råa nycklar — endast till handtag som pekar på nycklar inuti Keymaster.
Android KeyStore implementerar det standard JCA-tjänsteleverantörsgränssnittet. När applikationen anropar Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”) delegerar Android Security Provider operationen till Keymaster via kedjan: Java → JNI → keystore service → Keymaster HAL.
Leverantören AndroidKeyStore registreras automatiskt när processen startar. Dess prioritet är högre än Bouncy Castle eller Conscrypt. Därför returneras i de flesta fall AndroidKeyStore när KeyStore.getInstance() anropas utan att ange leverantör. För explicit anrop, använd KeyStore.getInstance(“AndroidKeyStore”).
Varje Android-applikation har en isolerad behållare i KeyStore. Applikationer med samma UID (shared userId) kan ha delad åtkomst till vissa nycklar, men standardkonfigurationen garanterar att applikation A inte kan läsa applikation B:s nycklar.
load(null) — initialisering av KeyStore. Parametern är alltid null för AndroidKeyStore. setEntry — lagring av nyckel med angivande av KeyProtection (purposes, digest, padding). getEntry — hämtning av KeyStore.PrivateKeyEntry, SecretKeyEntry eller TrustedCertificateEntry. containsAlias — kontroll av om nyckeln finns. deleteEntry — borttagning av nyckel (oåterkallelig).
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 stödjer en bred uppsättning kryptografiska algoritmer som varierar beroende på Keymaster HAL-versionen på enheten. Utvecklaren kan få en lista över stödda algoritmer via KeyGenParameterSpec.Builder vid genereringsförsök — inkompatibla parametrar orsakar InvalidAlgorithmParameterException.
RSA (1024–4096 bit) — för signatur (PKCS1, PSS med SHA-1/SHA-256/SHA-384/SHA-512) och kryptering (OAEP med SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — för ECDSA-signatur och ECDH-nyckelavtal. X25519 och Ed25519 — från Android 12 (API 31) för moderna kryptografiska protokoll.
För asymmetriska nycklar Generera alltid inuti Keymaster, importera ALDRIG privata nycklar. Importerade privata nycklar är inte hårdvaruskyddade — de lagras i programvarulagret och är sårbara vid kompromettering av AP.
AES (128, 256 bit) — för symmetrisk kryptering i lägena CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — för autentisering av meddelanden. ChaCha20 (Android 12+) — för högpresterande strömkryptering med Poly1305-autentisering.
| Algoritm | Keymaster | Syfte | API |
|---|---|---|---|
| RSA | KM 1.0+ | Signatur, kryptering | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Symmetrisk kryptering | 23+ |
| HMAC | KM 2.0+ | Autentiseringskod | 23+ |
| ChaCha20 | KM 3.0+ | Strömkryptering | 31+ |
| X25519/E25519 | KM 3.0+ | Nyckelutbyte | 31+ |
KeyStore.PrivateKeyEntry — innehåller den privata nyckeln (ej exportbar) och certifikatkedjan. KeyStore.SecretKeyEntry — för symmetriska nycklar. KeyStore.TrustedCertificateEntry — för betrodda CA-certifikat. Offentliga nycklar är tillgängliga för export via keyStore.getCertificate(alias).publicKey.
Låt oss titta på ett fullständigt scenario: generering av en AES-nyckel för datakryptering och generering av en EC-nyckel för signatur med biometriskt skydd. Båda nycklarna skapas inuti Android KeyStore med hårdvarustöd.
AES-nyckeln skapas via KeyGenerator med KeyGenParameterSpec. Parametrar: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (rekommenderat läge med autentisering), ENCRYPTION_PADDING_NONE (för GCM behövs ingen padding).
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-nyckeln med userAuthenticationRequired=true kräver autentisering av användaren före varje signeringsoperation. För detta används BiometricPrompt med CryptoObject som innehåller ett Signature-objekt. Efter framgångsrik biometri tillåter Keymaster operationen.
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 ger hårdvarumässiga säkerhetsgarantier som programvarubaserade KeyStore (JKS, BKS) inte kan erbjuda. Nycklar skyddas på SoC-nivå och även fullständig kontroll över Android-användarutrymmet gör det inte möjligt att extrahera den privata nyckeln.
Key Attestation — en mekanism som gör det möjligt för applikationen (och servern) att verifiera i vilken miljö nyckeln skapades. Android Keystore signerar ett certifikat som innehåller en lista över nyckelegenskaper: algoritm, storlek, purges, hardware-backed (True/False), origin (GENERATED, IMPORTED). Servern verifierar certifikatkedjan till Googles rotcertifikat.
Detta är kritiskt för finansiella applikationer: servern kan kräva att nyckeln skapades i en hårdvarumiljö (Hardware-Backed = True) och avvisa nycklar skapade i programvarubaserad Keystore. Key Attestation förhindrar attacker där angriparen byter ut Keystore mot en emulator.
setInvalidatedByBiometricEnrollment(true) innebär att nyckeln automatiskt tas bort av Keymaster när användarens biometriska mallar ändras eller tas bort. Detta är skydd mot attacker där angriparen lägger till sitt eget fingeravtryck i ett befintligt konto. Efter att ett nytt fingeravtryck lagts till blir gamla nycklar otillgängliga.
Räknaren för misslyckade biometriska autentiseringsförsök hanteras också av Keymaster. Efter maxBiometricAttempt (inställs av tillverkaren, vanligtvis 5) blockerar Keymaster alla operationer med biometriska nycklar i 30 sekunder. Efter 10 misslyckade försök — tills enhetens lösenord (hemlig PIN) anges.
Vanliga frågor
Bouncy Castle (BKS) — är en programvarubaserad KeyStore som lagrar nycklar i en lösenordsskyddad fil. Android KeyStore använder hårdvaruisolering TEE/StrongBox. BKS-nycklar kan extraheras med root-åtkomst, Android KeyStore-nycklar kan inte. BKS är lämpligt för CA-certifikat, Android KeyStore för privata nycklar.
Ja, om PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY anges vid generering. Bästa praxis är dock att skapa separata nycklar för olika operationer. Detta begränsar skadan vid kompromettering av en av nycklarna och följer principen om lägsta behörighet.
Använd KeyStore.getKeyCharacteristics(alias), tillgängligt via android.security.keystore. Metoden returnerar en uppsättning flaggor: FLAG_HARDWARE — nyckel i TEE, FLAG_SECURE_ELEMENT — nyckel i StrongBox. Om det inte finns några flaggor — är nyckeln programvarubaserad.
Alla nycklar som skapats med setInvalidatedByBiometricEnrollment(true) kommer automatiskt att ogiltigförklaras av Keymaster. Vid användningsförsök kommer applikationen att få KeyPermanentlyInvalidatedException. Data som krypterats med dessa nycklar kommer att förloras oåterkalleligt.
Hårdvarunycklar (i TEE/StrongBox) stödjer inte säkerhetskopiering — de är bundna till den specifika enheten. Programvarunycklar kan inkluderas i Google Drive-säkerhetskopia. För att överföra data mellan enheter, kryptera data på servern och dekryptera på den nya enheten.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också