KeyStore (Android): ключови понятия, API и работа на криптографското хранилище

Автор: IT Sectr Публикувано: 2026-03-14 Време за четене: 10 мин

KeyStore (Android) — е реализация на криптографския провайдър Java Cryptography Architecture (JCA), интегрирана в Android за сигурно съхранение на ключове с възможност за хардуерна изолация. От Android 4.3 (API 18) KeyStore поддържа хардуерни ключове чрез Keymaster HAL, а от Android 9 (API 28) — StrongBox Keymaster за ключове в специализиран Secure Element. Според Android Security Documentation, провайдърът „AndroidKeyStore” заменя стандартните Bouncy Castle или OpenSSL KeyStore, осигурявайки системна защита срещу неавторизирано извличане на ключове.

Основни положения

  • Android KeyStore — JCA провайдър за съхранение на ключове с поддръжка на TEE, StrongBox и биометрична защита
  • KeyGenParameterSpec определя алгоритъм, предназначение, digest, padding и биометрия при създаването на ключ
  • Keymaster HAL изпълнява хардуерни криптографски операции на нива Software, TEE и StrongBox
  • Key Attestation (API 28+) позволява на сървъра да провери, че ключът е създаден в хардуерната среда на Android KeyStore
  • Алиас на ключа — низът, по който приложението има достъп до ключа в Keystore; един алиас съответства на един ключ

Какво е KeyStore в Android?

KeyStore в Android — не е отделно приложение или файл, а криптографски провайдър, който реализира интерфейса java.security.KeyStore. Той осигурява единен API за съхранение и използване на частни ключове, симетрични ключове и сертификати на доверени центрове (CA). Провайдърът е регистриран под името „AndroidKeyStore” и е достъпен чрез стандартния KeyStore.getInstance().

Еволюция на Android KeyStore

Преди Android 4.3, криптографските операции се изпълняваха програмно чрез Bouncy Castle. С Android 4.3 се появи Keymaster HAL 1.0, който позволи използването на TEE в ARM TrustZone. Android 6.0 (API 23) добави Keymaster 2.0 с поддръжка за хардуерно удостовяване по пръстов отпечатък. Android 9 (API 28) представи Keymaster 4.0 и StrongBox Keymaster за посветен Secure Element.

Всяка версия на Keymaster добавя нови възможности и подобрява изолацията на ключовете. Съвременните устройства (2022+) трябва да поддържат Keymaster 4.0 за сертифициране на Google Mobile Services, което гарантира наличието на TEE за всички Android приложения.

Архитектура и компоненти

Android KeyStore се състои от три нива: Java API (KeyStore, KeyPairGenerator), системен процес keystore (C++, работи като system service) и Keymaster HAL (библиотека в TEE или Secure Element). Приложението вика API, keystore услугата насочва заявката към Keymaster, операцията се изпълнява в защитена среда.

Всички частни ключове се съхраняват в TEE и не могат да бъдат прочетени от потребителското пространство. Дори системната keystore услуга няма достъп до суровите ключове — само до држатки, които указват към ключове внутрен в Keymaster.

Как работи KeyStore като криптопровайдър?

Android KeyStore реализира стандартния интерфейс на доставчика на услуги JCA. Когато приложението вика Cipher.getInstance(„RSA/ECB/PKCS1Padding”, „AndroidKeyStore”), Android Security Provider делегира операцията на Keymaster чрез веригата: Java → JNI → keystore service → Keymaster HAL.

Регистрация на провайдъра

Провайдърът AndroidKeyStore се регистрира автоматично при стартирането на процеса. Неговият приоритет е по-висок от този на Bouncy Castle или Conscrypt. Ето защо при викане на KeyStore.getInstance() без посочване на провайдър, в повечето случаи се върща AndroidKeyStore. За изрично викане използвайте KeyStore.getInstance(„AndroidKeyStore”).

Всяко Android приложение има изолиран контейнер в KeyStore. Приложенията с еднаква UID (shared userId) могат да имат споделен достъп до определени ключове, но стандартната конфигурация гарантира, че приложение A не може да чете ключовете на приложение B.

Методи на KeyStore и тяхните характеристики

load(null) — инициализация на KeyStore. Параметърът е винаги null за AndroidKeyStore. setEntry — запазване на ключ с посочване на KeyProtection (purposes, digest, padding). getEntry — получаване на KeyStore.PrivateKeyEntry, SecretKeyEntry или TrustedCertificateEntry. containsAlias — проверка за наличие на ключ. deleteEntry — изтриване на ключ (необратимо).

kotlin
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 поддържа широк набор от криптографски алгоритъми, който се различава в зависимост от версията на Keymaster HAL на устройството. Разработчикът може да получи списък на поддържаните алгоритъми чрез KeyGenParameterSpec.Builder при опит за генериране — несъвместимите параметри причиняват InvalidAlgorithmParameterException.

Асиметрични алгоритъми

RSA (1024–4096 бита) — за подпис (PKCS1, PSS с SHA-1/SHA-256/SHA-384/SHA-512) и шифриране (OAEP с SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — за ECDSA подпис и ECDH споразумяване на ключове. X25519 и Ed25519 — от Android 12 (API 31) за съвременни криптографски протоколи.

За асиметрични ключове Винаги генерирайте внутрен на Keymaster, НИКОГА не импортирайте частни ключове. Импортираните частни ключове не са хардуерно защитени — те се съхраняват в програмния слой и са уязвими при компромитиране на AP.

Симетрични алгоритъми

AES (128, 256 бита) — за симетрично шифриране в режими CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — за удостовяване на съобщения. ChaCha20 (Android 12+) — за високопроизводително потоково шифриране с удостовяване Poly1305.

АлгоритъмKeymasterПредназначениеAPI
RSAKM 1.0+Подпис, шифриране18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+Симетрично шифриране23+
HMACKM 2.0+Код за удостовяване23+
ChaCha20KM 3.0+Потоково шифриране31+
X25519/E25519KM 3.0+Размяна на ключове31+

Типове ключове и тяхното сериализиране

KeyStore.PrivateKeyEntry — съдържа частен ключ (неизносим) и верига от сертификати. KeyStore.SecretKeyEntry — за симетрични ключове. KeyStore.TrustedCertificateEntry — за доверени CA сертификати. Публичните ключове са на разположение за изнасяне чрез keyStore.getCertificate(alias).publicKey.

Пример за генериране и използване на ключове

Нека разгледаме един пълен сценарий: генериране на AES ключ за шифриране на данни и генериране на EC ключ за подпис с биометрична защита. И двата ключа се създават внутрен в Android KeyStore с хардуерна поддръжка.

Генериране на AES ключ за шифриране

AES ключът се създава чрез KeyGenerator с KeyGenParameterSpec. Параметри: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (препоръчан режим с удостовяване), ENCRYPTION_PADDING_NONE (за GCM padding не е необходим).

kotlin
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 ключът с userAuthenticationRequired=true изисква удостовяване на потребителя преди всяка операция подпис. За това се използва BiometricPrompt с CryptoObject, съдържащ Signature обект. След успешна биометрия, Keymaster разрешава операцията.

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

KeyStore и сигурност на устройството

Android KeyStore осигурява хардуерни гаранции за сигурност, които програмните KeyStore (JKS, BKS) не могат да предоставят. Ключовете са защитени на ниво SoC и дори пълен контрол над потребителското пространство на Android не позволява извличане на частен ключ.

Key Attestation (Android 8.1+)

Key Attestation — механизъм, който позволява на приложението (и сървъра) да провери в каква среда е създаден ключът. Android Keystore подписва сертификат, съдържащ списък на характеристиките на ключа: алгоритъм, размер, purges, hardware-backed (True/False), origin (GENERATED, IMPORTED). Сървърът проверява веригата от сертификати до основния сертификат на Google.

Това е критично за финансовите приложения: сървърът може да изисква ключът да е създаден в хардуерна среда (Hardware-Backed = True) и да отказва ключове, създадени в програмен KeyStore. Key Attestation предотвратява атаки, при които нападатият подменя KeyStore с емулатор.

Инвалидация на ключове при промяна на биометрия

setInvalidatedByBiometricEnrollment(true) означава, че ключът ще бъде автоматично премахнат от Keymaster при промяна или изтриване на биометричните шаблони на потребителя. Това е защита срещу атаки, при които нападатият добавя своя отпечатък към съществуващ акаунт. След добавяне на нов отпечатък, старите ключове стават недостъпни.

Броячът на неуспешните опити за биометрично удостовяване също се управлява от Keymaster. След maxBiometricAttempt (настроен от производителя, обикновено 5) Keymaster блокира всички операции с биометрични ключове за 30 секунди. След 10 неуспешни опита — до въвеждане на паролата на устройството (тайния PIN).

Често задавани въпроси

Каква е разликата между Android KeyStore и Bouncy Castle KeyStore?

Bouncy Castle (BKS) — програмен KeyStore, който съхранява ключовете в файл, защитен с парола. Android KeyStore използва хардуерна изолация TEE/StrongBox. Ключовете на BKS могат да бъдат извлечени с root достъп, ключовете на Android KeyStore — не. BKS е подходящ за CA сертификати, Android KeyStore — за частни ключове.

Може ли един ключ да се използва за шифриране и подпис?

Да, ако при генерирането е посочено PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY. Най-добрата практика обаче е да създавате отделни ключове за различни операции. Това ограничава щетите при компромитиране на един от ключовете и съответства на принципа на най-малкото право.

Как да разбера дали ключът в Android KeyStore е хардуерен?

Използвайте KeyStore.getKeyCharacteristics(alias), достъпен чрез android.security.keystore. Методът върща набор от флагове: FLAG_HARDWARE — ключ в TEE, FLAG_SECURE_ELEMENT — ключ в StrongBox. Ако няма флагове — ключът е програмен.

Какво става при изтриване на всички биометрични шаблони?

Всички ключове, създадени с setInvalidatedByBiometricEnrollment(true), ще бъдат автоматично инвалидирани от Keymaster. При опит за използване приложението ще получи KeyPermanentlyInvalidatedException. Данните, шифрирани с тези ключове, ще бъдат необратимо загубени.

Поддържа ли Android KeyStore резервно копиране на ключове?

Хардуерните ключове (в TEE/StrongBox) не поддържат резервно копиране — те са свързани с конкретното устройство. Програмните ключове могат да бъдат включени в резервното копиране на Google Drive. За пренасяне на данни между устройства, шифрирайте данните на сървъра и дешифрирайте на новото устройство.

Обобщение

  • Android KeyStore — JCA провайдър за хардуерно изолирано съхранение на ключове чрез Keymaster HAL в TEE/StrongBox
  • KeyGenParameterSpec конфигурира алгоритъма, размера, purges, digest, биометрията и времевите ограничения на ключа
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — поддържани алгоритъми с различни нива на Keymaster
  • Key Attestation (API 28+) позволява на сървърната страна да провери хардуерния произход на ключа
  • Биометрична защита на ключовете чрез setUserAuthenticationRequired + BiometricPrompt с CryptoObject
  • Инвалидация на ключове при промяна на биометрия предотвратява неавторизирано използване на добавени отпечатъци
  • Използвайте Android KeyStore за генериране и съхранение на криптографски ключове с хардуерна защита в Android приложения

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също