Android Keystore — криптографічний провайдер, який генеруєта зберігаєключі шифрування в ізольованому середовищі виконання (TEE), недоступному навіть для операційної системи. За даними AOSP Security Documentation (2025), Keystore використовується більше ніж у 80% Android-додатків з топ-100 Google Play для захисту токенів та шифрування даних. Розуміння Android Keystore критично важливе для безпечного зберігання ключів на Android.
Головне
Android Keystore — системний компонент платформи Android, який надаєAPI для генерації, зберігання та використання криптографічних ключів у захищеному середовищі. На відміну від програмних криптографічних бібліотек (Bouncy Castle, Conscrypt), Keystore гарантує, що приватні ключі ніколи не залишають ізольовану область виконання.
Keystore з’явився в Android 4.3 (API 18) як програмний провайдер з підтримкою RSA. Починаючи з Android 6.0 (API 23), Keystore отримав апаратну підтримку через Keymaster Hardware Abstraction Layer (HAL), яка делегуєкриптографічні операції Trusted Execution Environment (TEE) на сумісних пристроях. За даними Android Compatibility Definition Document (2025), всі пристрої з Android 9+ зобов’язані підтримувати апаратний Keystore через TEE або StrongBox.
Ключі в Keystore ідентифікуються за псевдонімом (alias) — рядком, який передається при створенні або завантаженні ключа. Keystore не дозволяєотримати сирий матеріал ключа: методи getEncoded() повертають null для ключів, створених в Keystore. Це фундаментальна відмінність від програмних ключів — зловмисник не може вилучити приватний ключ навіть при повному контролі над пристроєм.
Keystore інтегрований з іншими механізмами безпеки Android: біометричною аутентифікацією (BiometricPrompt), шифруванням на рівні файлів (File-Based Encryption) та функціями перевірки SafetyNet/Play Integrity. Ключі можна налаштувати на автоматичне видалення при певних умовах: при видаленні код-пароля, при додаванні нового відбитку пальця або після закінчення терміну дії.
Архітектура Android Keystore включаєтри рівні реалізації, які відрізняються ступенем апаратного захисту. Рівень залежить від можливостей апаратного забезпечення пристрою.
TEE (Trusted Execution Environment) — ізольована область, що працюєпаралельно з основною ОС на тому ж процесорі. TEE використовуєтехнологію ARM TrustZone, яка розділяєфізичне ядро процесора на два віртуальні: Normal World (Android) та Secure World (TEE). Код в Secure World маєдоступ до пам’яті та периферії, недоступних з Normal World.
Коли додаток викликаєкриптографічну операцію через Keystore, запит передається через Keymaster HAL в TEE, де операція виконується апаратно. Результат повертається в додаток, але приватний ключ залишається в захищеній пам’яті TEE. TEE сертифікований на відповідність GlobalPlatform TEE Protection Profile і єобов’язковою вимогою для Android 9+ на пристроях з процесорами, що підтримують TrustZone.
TEE підтримуєалгоритми AES/GCM (128, 256 біт), RSA (2048, 4096 біт), EC (P-256, P-384, P-521) та HMAC-SHA256. Продуктивність TEE нижча, ніж програмна криптографія (на 20–40%), але для типових операцій (підпис JWT, розшифрування ключа сесії) затримка не перевищує10–50 мс.
StrongBox — виділений чип безпеки, фізично окремий від основного процесора. На відміну від TEE, який розподіляєчас процесора з Android, StrongBox маєвласний CPU, оперативну пам’ять, True Random Number Generator (TRNG) та захищене сховище (One-Time Programmable memory). StrongBox сертифікований на Common Criteria EAL 4+ та Secure IC Protection Profile.
StrongBox доступний на пристроях з Android 9+ за умови наявності відповідного чипа (наприклад, Titan M на Google Pixel, Knox на Samsung Galaxy). Розробник вмикаєStrongBox через прапорець setIsStrongBoxBacked(true) в KeyGenParameterSpec. При відсутності апаратної підтримки прапорець ігнорується, і Keystore перемикається на TEE.
Обмеження StrongBox: підтримуєобмежений набір алгоритмів (AES-256, EC P-256, HMAC-SHA256), черга операцій — не більше однієї одночасно, кількість операцій — обмежена ресурсами чипа. StrongBox не призначений для високонавантажених сценаріїв — використовуйте TEE для частих операцій і StrongBox тільки для критичних ключів (мастер-ключі шифрування, ключі підпису).
Software-based Keystore — програмна реалізація, яка використовується на пристроях без апаратної підтримки TEE або StrongBox. Ключі зберігаються в зашифрованому вигляді в файловій системі, але приватний ключ може бути тимчасово розшифрований в оперативній пам’яті. Програмний Keystore менш безпечний — зловмисник з root-доступом може перехопити ключ в пам’яті.
Починаючи з Android 12 (API 31), Google вимагаєапаратної підтримки Keystore для всіх нових пристроїв. Пристрої з Android 9–11 можуть мати програмний Keystore на бюджетних моделях. Розробник може перевірити рівень захисту через KeyStore.getKeyCharacteristics() — атрибут SECURITY_LEVEL_TRUSTED_ENVIRONMENT або SECURITY_LEVEL_STRONGBOX підтверджуєапаратний захист.
Android Keystore підтримуєширокий набір криптографічних алгоритмів, розділених на категорії залежно від типу ключа. Вибір алгоритму впливаєна продуктивність, сумісність та рівень безпеки.
AES (Advanced Encryption Standard) — симетричне шифрування для захисту даних на пристрої. Рекомендований режим: AES/GCM/NoPadding (256 біт). GCM забезпечуєаутентифіковане шифрування (AEAD) — перевірку цілісності зашифрованих даних. Розмір IV (Initialization Vector): 12 байтів для GCM. Не використовуйте AES/ECB — він не забезпечуєналежного захисту.
RSA (Rivest–Shamir–Adleman) — асиметричне шифрування для захисту ключів сесії та цифрового підпису. Рекомендований розмір: 2048 або 4096 біт. Режими: RSA/ECB/PKCS1Padding (шифрування) та RSA/ECB/PKCS1Sign (підпис). RSA 1024 вважається застарілим і не рекомендується для нових додатків (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — асиметрична криптографія на еліптичних кривих для підпису та обміну ключами. Підтримувані криві: secp256r1 (P-256, обов’язкова), secp384r1 (P-384) та secp521r1 (P-521). EC забезпечуєпорівнянну з RSA безпеку при значно меншому розмірі ключа. P-256 рекомендується для більшості сценаріїв: він підтримується всіма пристроями та забезпечує128-бітний рівень безпеки.
HMAC (Hash-based Message Authentication Code) — симетрична аутентифікація повідомлень. Підтримувані хеш-функції: SHA-256, SHA-384, SHA-512. HMAC використовується для перевірки цілісності та автентичності даних, наприклад, для верифікації webhook-запитів або перевірки цілісності конфігурації.
Всі алгоритми можуть бути прив’язані до біометричної аутентифікації через KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). На Android 11+ доступний прапорець setUserAuthenticationParameters() із зазначенням таймауту (в секундах), протягом якого ключ доступний після біометричної аутентифікації без повторного запиту.
Розглянемо практичні приклади роботи з Android Keystore на Kotlin: генерація ключа AES, шифрування даних та створення асиметричної пари для підпису.
Приклад створює256-бітний AES/GCM ключ із прив’язкою до біометричної аутентифікації. Ключ недоступний для експорту через getEncoded().
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
fun generateAesKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setKeySize(256)
.setBlockModes(KeyProperties.KEY_BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
val generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore"
)
generator.init(spec)
generator.generateKey()
}
Приклад шифруєдані з використанням ключа з Android Keystore. Cipher отримуєключ за псевдонімом, ініціалізуєAES/GCM шифрування та повертаєзашифровані дані разом з IV.
fun encryptData(alias: String, plaintext: ByteArray): ByteArray {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val iv = cipher.getIV()
val encrypted = cipher.doFinal(plaintext)
// IV + зашифровані дані
return iv + encrypted
}
fun decryptData(alias: String, ciphertextWithIv: ByteArray): ByteArray {
val iv = ciphertextWithIv.copyOfRange(0, 12)
val encrypted = ciphertextWithIv.copyOfRange(12, ciphertextWithIv.size)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
val spec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec)
return cipher.doFinal(encrypted)
}
Приклад створюєпару RSA-2048 ключів в Keystore із прив’язкою до StrongBox. Приватний ключ використовується для підпису, публічний — може бути експортований через getEncoded().
fun generateRsaKeyPair(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_SIGN or
KeyProperties.PURPOSE_VERIFY
)
.setKeySize(2048)
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setIsStrongBoxBacked(true)
.build()
val pair = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
).apply { init(spec) }
.generateKeyPair()
// Публічний ключ можна експортувати
val publicKey = pair.public // X509EncodedKeySpec
}
Ефективне використання Android Keystore вимагаєдотримання правил, які забезпечують максимальний захист при збереженні продуктивності.
Використовуйте KeyGenParameterSpec з мінімально необхідними параметрами: зазначайте лише ті purpose, block modes та paddings, які реально використовуються. Надлишкові параметри (наприклад, PURPOSE_ENCRYPT для ключа, який використовується лише для підпису) створюють зайві вектори атаки. Android рекомендуєявно вказувати дайджест для підпису — SHA256 мінімальний допустимий рівень (SHA1 застарів).
Прив’язуйте ключі до біометрії для критичних операцій: setUserAuthenticationRequired(true) гарантує, що ключ можна використовувати лише після біометричної аутентифікації. На Android 11+ використовуйте setUserAuthenticationParameters() із таймаутом (рекомендовано 30–60 секунд), щоб не запитувати біометрію на кожну операцію в межах однієї сесії. setInvalidatedByBiometricEnrollment(true) автоматично видаляєключ при додаванні нового відбитку або обличчя — це запобігаєдоступу через старі біометричні дані.
Перевіряйте рівень безпеки на етапі ініціалізації: використовуйте KeyStore.getKeyCharacteristics() для визначення SECURITY_LEVEL. Якщо пристрій підтримуєлише програмний Keystore (SECURITY_LEVEL_SOFTWARE), прийміть рішення: або відмовитися від функціоналу, або використовувати додаткове шифрування (наприклад, обгортку ключа через пароль користувача). Не покладайтеся на StrongBox, якщо він не гарантований — завжди вказуйте прапорець setIsStrongBoxBacked(true) та перевіряйте результат через getKeyCharacteristics.
Оновлюйте ключі за розкладом: криптографічні ключі мають рекомендований термін життя. NIST SP 800-57 рекомендуєзмінювати AES ключі кожні 1–2 роки, RSA/EC пари — кожні 2–3 роки. Реалізуйте механізм ротації ключів: при запуску додатка перевіряйте дату створення ключа (KeyGenParameterSpec.Builder.setKeyValidityStart/End) та генеруйте новий ключ при закінченні терміну. Старі дані, зашифровані старим ключем, повинні бути розшифровані та перешифровані новим.
Не використовуйте Keystore для великих даних: Keystore призначений для зберігання ключів (кілька сотень байтів), а не для шифрування великих файлів. Для шифрування даних використовуйте схему: згенеруйте випадковий AES ключ (DEK — Data Encryption Key), зашифруйте дані цим ключем, а DEK зашифруйте ключем Keystore (KEK — Key Encryption Key). Android EncryptedSharedPreferences використовуєсаме цю схему: мастер-ключ в Keystore, дані — AES-256 GCM.
Часто задавані питання
Ні, Android Keystore спроектований так, щоб приватний ключ ніколи не залишав TEE або StrongBox. Метод getEncoded() повертаєnull для ключів, створених в Keystore. Ключ можна використовувати лише через Cipher, Signature або Mac API — сирий матеріал недоступний.
TEE (TrustZone) — віртуальна ізоляція на тому ж процесорі, використовуєрозподіл часу. StrongBox — окремий чип з власним CPU та пам’яттю. StrongBox безпечніший (Common Criteria EAL 4+), але повільніший та підтримуєменше алгоритмів. TEE підходить для частих операцій, StrongBox — для критичних ключів.
Використовуйте KeyStore.getKeyCharacteristics() після генерації ключа з прапорцем setIsStrongBoxBacked(true). Атрибут SECURITY_LEVEL_STRONGBOX підтверджуєапаратну підтримку. Якщо пристрій не підтримуєStrongBox, Keystore перемикається на TEE без помилки — необхідно явно перевіряти рівень безпеки.
Ключі в Keystore автоматично видаляються при видаленні додатка з пристрою. На Android 10+ ключі можуть зберігатися, якщо додаток маєпрапорець allowBackup=true в маніфесті, але вони будуть недоступні після перевстановлення. Рекомендується генерувати ключі заново при чистому встановленні.
Ні, Android Keystore прив’язаний до апаратного забезпечення конкретного пристрою. Ключ, створений в TEE одного пристрою, неможливо передати на інший. Для кросплатформенного шифрування використовуйте схему: Keystore захищаєключ на пристрої, а ключі сесії передаються через захищений API з використанням асиметричного шифрування.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також