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-сервис не имеет доступа к raw-ключам — только к хэндлам, указывающим на ключи внутри 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) для современных криптографических протоколов.

Для асимметричных ключей Always generate inside Keymaster, NEVER import private keys. Импортированные закрытые ключи не защищены аппаратно — они хранятся в программном слое и уязвимы при компрометации 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. Однако лучшая практика — создавать отдельные ключи для разных операций. Это ограничивает ущерб при компрометации одного из ключей и соответствует принципу least privilege.

Как узнать, аппаратный ли ключ в 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также