Keystore (Android): шта је, архитектура и принципи рада

Аутор: IT Sectr Објављено: 2026-03-14 Време читања: 10 мин

Android Keystore — је системски механизам Android-а за безбедно чување криптографских кључева у хардверској изолацији. Систем користи Trusted Execution Environment (TEE) на уређајима са ARM TrustZone или посебни Secure Element за заштиту кључева на нивоу чипа. Према Android Open Source Project-u, Keystore подржава алгоритме RSA, EC, AES и HMAC са генерацијом кључева директно у заштићеном окружењу.

Главно

  • Android Keystore — провајдер KeyStore који изолира криптографске кључеве од корисничког простора Android-а
  • Кључеви се генеришу унутар TEE или Secure Element и никада не напуштају заштићено окружење у отвореном облику
  • Android 9+ додаје KeyGenParameterSpec.Builder са параметрима: purpose, digest, padding, userAuthenticationRequired
  • Биометријска заштита кључева захтева потврду корисника кроз BiometricPrompt пре сваке операције
  • Keymaster HAL — хардверски ниво апстракције који реализује криптографске операције у TEE или Secure Element

Шта је Android Keystore?

Android Keystore — је криптографски провајдер (provider) имплементиран у Android-у од API 1 (Android 1.0), али пуна хардверска подршка се појавила са Android 4.3 (API 18). Keystore решава проблем безбедног чувања приватних кључева на такав начин да чак и при компромитацији оперативног система, нападач не може да извуче кључеве у отвореном облику.

Архитектура KeyStore-а на Android-у

Архитектура Android Keystore-a састоји се од три нивоа: примјенског API (java.security.KeyStore), системске услуге (keystore daemon) и хардверског нивоа (Keymaster HAL). Апликација приступа кроз стандардни API Java Cryptography Architecture (JCA), а системска услуга усмерава захтеве ка Keymaster-у који ради у TEE.

Све криптографске операције са кључевима (потпис, дешифровање) се извршавају унутар TEE или Secure Element. Кључеви никада не напуштају заштићено окружење — апликација добија само идентификатор (алиас) за позивање на кључ. Ово је фундаментална разлика у односу на софтверске KeyStore-ове, где су кључеви потенцијално доступни у меморији процеса.

Разлика од Java KeyStore

Стандардни JKS (Java KeyStore) или BKS (Bouncy Castle) чувају кључеве у датотекама заштићеним лозинком. Android Keystore чува кључеве у хардверској изолацији, где су заштићени чак и од root корисника. JKS је рањив на директан приступ фајл систему, Android Keystore — није.

Друга разлика: у Android Keystore-у кључеви имају строге параметре коришћења (purpose — само sign/verify/encrypt/decrypt) који се постављају при генерацији. Они се не могу касније мењати, што спречава злоупотребу кључа.

Како ради Android Keystore?

При креирању новог кључа, апликација позива KeyPairGenerator или KeyGenerator са KeyGenParameterSpec-ом, који садржи све параметре будућег кључа. Систем прослеђује захтев Keymaster HAL-у, који генерише кључ унутар TEE и враћа идентификатор.

Процес генерације кључа

Метода KeyGenParameterSpec.Builder прихвата обавезне параметре: име кључа у Keystore-у, намену (PURPOSE_SIGN, PURPOSE_ENCRYPT), алгоритам (RSA, EC, AES). Додатно: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (биометрија), keyValidityStart/End (временска ограничења).

Након постављања параметара, KeyPairGenerator.generateKeyPair() враћа KeyPair, где је PrivateKey објекат који делегира операције Keymaster-у. Јавни кључ може да се извуче, приватни — не може. Постоји само унутар TEE.

kotlin
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()
}

Потписивање и верификација

Signature за ECDSA или RSA-PSS се креира кроз стандардни API: Signature.getInstance(algorithm).initSign(privateKey). Операција потписивања се извршава у TEE: апликација шаље податке, Keymaster их хардверски потписује и враћа потпис. Кључ и подаци се не мешају у заједничкој меморији.

За биометријску заштиту потребно је пре потписивања аутентификовати корисника кроз BiometricPrompt. Без успешне аутентификације, Keymaster не извршава операцију, враћајући CryptoAuthenticationException.

kotlin
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 sa CryptoObject(signature) zahteva FaceID/PIN
}

Типови KeyStore складишта

Android подржава два начина чувања кључева: софтверски (на уређајима без TEE) и хардверски (на уређајима са TEE или Secure Element). Начин зависи од могућности SoC-а и верзије Android-а.

Софтверски KeyStore (само софтвер)

На уређајима без Trusted Execution Environment-а (пре Android 4.3 или буџетни SoC) кључеви се чувају у шифрованом облику коришћењем главног кључа изведеног из лозинке заклучаног екрана. Овај начин је мање сигуран — кључеви су доступни у меморији процеса приликом извршавања криптографских операција.

Ниво заштите се заснива на шифровању датотеке KeyStore-а помоћу AES-256-GCM. Кључ за шифровање се генерише на основу лозинке или PIN-кода корисника кроз Scrypt (PBKDF2 са великим бројем итерација).

Хардверски KeyMaster (TEE/Secure Element)

На савременим уређајима користи се Keymaster 4.x у TEE (ARM TrustZone). Кључеви се генеришу, чувају и користе искључиво унутар TrustZone-а. Чак ни и језгро Linux-а нема приступ приватним кључевима — само Keymaster HAL може да обавља операције.

Secure Element (нпр. eSE у Samsung Knox-у или StrongBox у Google Pixel 3+) — је посебан чип са сопственим процесором и меморијом. Сертификован према Common Criteria EAL 4+ и пружа максимални ниво заштите, укључујући заштиту од физичког отварања.

ТипМесто чувањаНиво заштитеДоступно од API
SoftwareДатотека /data/misc/keystoreСредњи (AES-256)API 1+
Keymaster 3TEE (TrustZone)ВисокAPI 23+
Keymaster 4TEE + Secure I/OВрло високAPI 28+
StrongBoxХардверски Secure ElementМаксималанAPI 28+, опционално

Рад са KeyStore API

Android Keystore је интегрисан у Java Cryptography Architecture (JCA). За приступ провајдеру користи се стандардни KeyStore.getInstance("AndroidKeyStore"). API је доступан од API 18.

Креирање и учитавање KeyStore-а

Метода KeyStore.load(null) учитава контејнер KeyStore текуће апликације. Лозинка није потребна — Android користи контекст апликације и њен UID за разграничење приступа. Свака апликација види само своје уносе, осим ако се користи заједнички UID.

Методе setEntry и getEntry раде са KeyStore.PrivateKeyEntry, SecretKeyEntry или TrustedCertificateEntry. Параметар ProtectionParameter је увијек null за Android Keystore (заштита је имплементирана на нивоу система).

kotlin
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-а може се утврдити у којем окружењу је похрањен кључ: софтверском KeyStore-у, TEE или StrongBox-у. Метода getKeyCharacteristics() враћа скуп заставица: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (биометрија).

Алгоритми и безбедност

Android Keystore подржава широк скуп криптографских алгоритама, подељен у три категорије: асиметрични, симетрични и MAC. Подршка за одређене алгоритме зависи од верзије Keymaster HAL-а.

Подржани алгоритми

RSA (1024–4096 бита) — за потпис (PKCS1, PSS) и шифровање (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — за ECDSA потпис и ECDH размену. AES (128, 256 бита) — за симетрично шифровање у CBC, CTR, GCM начинима. HMAC (SHA1, SHA256, SHA512) — за аутентификацију порука.

За сваки кључ поставља се setPurposes, који ограничава могуће операције. RSA кључ са PURPOSE_SIGN не може да се користи за шифровање, чак и ако нападач има приступ API-ју. Ово је принуђавање коришћења кључа на хардверском нивоу.

Заштита од компромитације

Keymaster укључује бројач неуспешних покушаја биометријске аутентификације. Након одређеног броја неуспешних покушаја (подешиво кроз setInvalidatedByBiometricEnrollment) кључ постаје недоступан и захтева брисање/регенерацију. При брисању свих биометријских шаблона, сви кључеви са userAuthenticationRequired=true аутоматски постају неважећи.

Такође, подржано је Key Attestation (Android 8.1+): на захтев апликације, Keymaster потписује цертификат са информацијама о карактеристикама кључа (хардверски/софтверски, алгоритам, purges). Сервер може да провери овај цертификат да би потврдио да је кључ креиран у поузданом окружењу.

Често постављана питања

Која је разлика између Android Keystore и KeyStore у Java-и?

Java KeyStore чува кључеве у датотеци заштићеној лозинком (JKS, BKS). Android Keystore користи хардверску изолацију TEE или Secure Element. Java KeyStore је рањив на root приступ, Android Keystore — није, јер приватни кључеви никада не напуштају заштићено окружење.

Може ли се увезти постоћећи кључ у Android Keystore?

Да, путем KeyStore.setEntry са KeyProtection. Међутим, увезени кључ неће имати хардверску заштиту — биће складиштен у софтверском Keystore-у, шифрован главним кључем. За максималну безбедност, увијек генеришите кључеве унутар Keystore-а.

Како проверити да ли уређај подржава хардверски KeyStore?

Користите KeyChain.isBoundKeyAlgorithm или проверите KeyCharacteristics након генерације кључа. Присуство FLAG_HARDWARE у карактеристикама значи да је кључ креиран у TEE. Такође можете проверити android.security.keystore.isHardwareBacked().

Шта се догађа са кључевима при брисању апликације?

При брисању апликације, Android уклања све њене кључеве из Keystore-а. Подаци се неопозиво губе. При поновној инсталацији, апликација мора да генерише нове кључеве. Бекап кључева путем TEE је немогућ из архитектурних разлога.

Како KeyStore штити од напада кроз дебагирање?

На закључаном уређају, Keymaster не обавља никакве операције. Кључеви са userAuthenticationRequired=true захтевају биометријску потврду сваки пут. Чак и са root приступом, нападач не може директно позвати Keymaster — само кроз Android Keystore service.

Резиме

  • Android Keystore — JCA криптографски провајдер са хардверском изолацијом кључева кроз TEE или Secure Element
  • Кључеви се генеришу унутар TrustZone-а и никада не напуштају заштићено окружење у отвореном облику
  • KeyGenParameterSpec поставља параметре кључа: purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL реализује три нивоа: софтверски (software), TEE (Keymaster 3/4) и StrongBox (хардверски Secure Element)
  • Биометријска заштита кључева се обезбеђује кроз setUserAuthenticationRequired и BiometricPrompt са CryptoObject
  • Key Attestation (API 28+) омогућава проверу на серверу да је кључ креиран у хардверском окружењу
  • Користите Android Keystore за чување приватних кључева за потпис, шифровање и аутентификацију у Android апликацијама

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође