Secure Storage (безпечне зберігання) — комплекс методів і технологій для захисту конфіденційних даних на пристрої: токенів, ключів шифрування, платіжної інформації та персональних даних користувачів. За даними OWASP Mobile Top 10 (2024), небезпечне зберігання даних входить до першої трійки найкритичніших ризиків. Грамотна реалізація безпечного зберігання запобігає витоку даних навіть за фізичного доступу до пристрою.
Головне
Secure Storage — практика зберігання конфіденційних даних мобільного застосунку таким чином, щоб вони були недоступні іншим застосункам, шкідливому ПЗ і зловмиснику за фізичного доступу до пристрою. На відміну від звичайного зберігання, Secure Storage використовує шифрування, ізоляцію та апаратний захист.
Не всі дані потребують Secure Storage: зображення профілю або кеш новин можна зберігати у звичайній файловій системі. Однак ключі шифрування, токени автентифікації, платіжні дані, приватні ключі та біометричні шаблони мають бути захищені. За даними Google Security Blog (2025), 67% вразливостей у мобільних застосунках пов'язані зі зберіганням секретів у відкритому вигляді.
Кожна мобільна платформа надає власні механізми Secure Storage: Android — Keystore та EncryptedSharedPreferences, iOS — Keychain та Data Protection API. Ці механізми інтегровані з апаратними модулями безпеки (TEE, Secure Enclave) і гарантують, що дані неможливо прочитати навіть за джейлбрейка чи рутування пристрою.
Правильний вибір методу Secure Storage залежить від типу даних, сценарію використання та вимог до продуктивності. Розуміння архітектури кожного механізму дозволяє розробнику ухвалити правильне архітектурне рішення.
Платформа Android надає кілька рівнів захисту даних, від апаратного сховища ключів до зашифрованих SharedPreferences. Вибір залежить від чутливості даних і вимог до продуктивності.
Android Keystore — криптографічний провайдер, який генерує та зберігає ключі в ізольованому середовищі виконання (TEE — Trusted Execution Environment) на пристроях із підтримкою апаратного захисту. Ключі ніколи не покидають TEE: криптографічні операції виконуються всередині захищеної області, недоступної навіть операційній системі.
Починаючи з Android 9 (API 28), Keystore підтримує StrongBox Keymaster — виділений чіп безпеки з власним CPU, True Random Number Generator (TRNG) і захищеною пам'яттю. StrongBox сертифікований на відповідність Common Criteria EAL 4+ і є найбільш захищеним рівнем зберігання ключів на Android. Для використання StrongBox необхідно явно вказати прапорець inStrongBox() під час генерації ключа.
Keystore підтримує алгоритми: AES/GCM/NoPadding (256 біт), EC (secp256r1, secp384r1), RSA (2048–4096 біт) і HMAC-SHA256. Усі ключі можуть бути прив'язані до біометричної автентифікації через setUserAuthenticationRequired(true).
EncryptedSharedPreferences — бібліотека з пакета AndroidX Security, яка автоматично шифрує всі дані, що зберігаються через SharedPreferences API. Значення шифруються ключем AES-256 GCM, а ключі — AES-256 SIV (синтетичний IV), що запобігає атакам за словником на назви ключів.
Основний ключ шифрування зберігається в Android Keystore, забезпечуючи дворівневий захист: Keystore захищає майстер-ключ, а EncryptedSharedPreferences захищає дані. Продуктивність шифрування становить менш ніж 5 мс на операцію читання/запису для типових даних (токен, налаштування), що робить бібліотеку придатною для користувацьких сценаріїв.
EncryptedSharedPreferences не призначена для великих обсягів даних (понад 5 МБ) — для них використовуйте зашифровану базу даних через SQLCipher або Room із шифруванням.
SQLCipher — розширення SQLite, яке шифрує всю базу даних посторінково з використанням AES-256-CBC. Кожна сторінка бази даних шифрується окремим ключем, похідним від майстер-пароля через PBKDF2. SQLCipher додає близько 5–15% накладних витрат на продуктивність залежно від розміру даних.
Інтеграція з Android здійснюється через бібліотеку net.zetetic:android-database-sqlcipher, яка надає API, сумісний зі стандартним SQLiteOpenHelper. Пароль для SQLCipher рекомендується зберігати в Keystore, а не в коді чи SharedPreferences.
Платформа iOS надає Keychain Services — основне захищене сховище, а також Data Protection API для шифрування файлів на рівні ОС.
Keychain — зашифрована база даних SQLite, у якій iOS зберігає паролі, ключі шифрування, сертифікати та нотатки. Кожен елемент Keychain (SecItem) зберігається в зашифрованому вигляді з використанням апаратного ключа, унікального для пристрою. Доступ до елемента контролюється через ACL (Access Control List), який може вимагати біометричну автентифікацію (Face ID, Touch ID) або код-пароль.
Keychain підтримує класи захисту (Protection Class), що визначають, коли дані доступні: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — дані доступні лише за розблокованого пристрою і не переносяться під час резервного копіювання. Цей клас рекомендується для більшості сценаріїв зберігання токенів автентифікації.
На iOS 15+ доступний Security framework із підтримкою апаратних ключів через Secure Enclave — виділений процесор Apple, який обробляє криптографічні операції та зберігає приватні ключі в ізольованій пам'яті. Secure Enclave підтримує алгоритми ECDSA (secp256r1) і ECDH для генерації ключів, які неможливо витягти з чіпа.
Data Protection — механізм iOS, який шифрує кожен файл на рівні файлової системи (APFS) з використанням ключа, прив'язаного до код-пароля пристрою. Розробник вказує рівень захисту через атрибут NSFileProtectionType під час створення файлу: NSFileProtectionComplete — файл доступний лише за розблокованого пристрою.
Data Protection працює автоматично на всіх пристроях з iOS 5+, якщо встановлено код-пароль. Шифрування виконується на апаратному рівні через Dedicated AES Engine процесора Apple, що забезпечує високу продуктивність — затримка шифрування практично непомітна для користувача. Для ввімкнення захисту в застосунку достатньо встановити атрибут захисту під час створення файлу через FileManager.
Data Protection не замінює Keychain для зберігання ключів — вона використовується для шифрування файлів, баз даних Core Data та інших великих обсягів даних. Комбінація Keychain (для ключів) і Data Protection (для файлів) забезпечує повний цикл безпечного зберігання на iOS.
Розглянемо практичні приклади Secure Storage з використанням вбудованих API Android та iOS.
Приклад показує ініціалізацію EncryptedSharedPreferences із майстер-ключем з Android Keystore. Усі подальші операції читання та запису автоматично шифруються й дешифруються.
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val prefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
prefs.edit()
.putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
.apply()
Приклад демонструє збереження та читання даних з iOS Keychain з використанням Security framework. Код використовує kSecAttrAccessibleWhenUnlockedThisDeviceOnly для максимального захисту.
import Security
func saveToKeychain(key: String, data: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
SecItemAdd(query as CFDictionary, nil)
}
func readFromKeychain(key: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(
query as CFDictionary, &result
)
return status == errSecSuccess ? result as? Data : nil
}
Приклад підключення до зашифрованої SQLite-бази через SQLCipher із паролем, що зберігається в Android Keystore.
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper
class SecureDBHelper(context: Context) :
SQLiteOpenHelper(context, "secure.db", null, 1) {
private val password = getKeyFromKeystore()
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
}
override fun onUpgrade(
db: SQLiteDatabase, oldVersion: Int, newVersion: Int
) {
onCreate(db)
}
}
// Використання: передаємо пароль під час відкриття
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)
Правильне використання Secure Storage потребує дотримання кількох фундаментальних принципів, які запобігають типовим помилкам розробників.
Визначте класифікацію даних: які дані потребують апаратного захисту (Keystore / Secure Enclave), які — шифрування на рівні ОС (EncryptedSharedPreferences / Data Protection), а які можна зберігати у звичайній файловій системі. Токени автентифікації, приватні ключі та платіжні дані — лише апаратний рівень. Налаштування користувача (тема, мова) — достатньо EncryptedSharedPreferences. Дані сесії (тимчасові кеші) можуть зберігатися в пам'яті або тимчасовій директорії.
Ніколи не зберігайте секрети в коді: рядки з API-ключами, паролями або seed-фразами у вихідному коді — груба помилка безпеки. Будь-який reverse engineering миттєво розкриє ці дані. Використовуйте Keystore для ключів, а для конфігурації — серверне завантаження під час запуску застосунку (remote config).
Використовуйте біометричну прив'язку для критичних операцій: Android Keystore та iOS Keychain підтримують прив'язку ключів до біометричної автентифікації. При кожному зверненні до ключа система запитує Face ID, Touch ID або біометрію Android (BiometricPrompt). Це гарантує, що навіть за повного контролю над пристроєм зловмисник не зможе використати збережені дані без власника.
Тестуйте захист: використовуйте інструменти аналізу захищеності — MobSF (Mobile Security Framework) для статичного аналізу, objection для runtime-тестування та Frida для обходу захисту. Перевіряйте, що дані недоступні після рутування чи джейлбрейка. Android дозволяє перевірити наявність root-доступу через SafetyNet Attestation або Play Integrity API, iOS — через перевірку цілісності Secure Enclave.
Регулярно оновлюйте криптографічні бібліотеки: вразливості в бібліотеках шифрування виявляються регулярно. Відстежуйте CVE для AndroidX Security, SQLCipher та Keychain-обгорток. Впровадьте систему автоматичних сповіщень про нові версії через Dependabot або Renovate.
За даними Apple Security Research (2025), правильна реалізація Secure Storage запобігає 96% атак, спрямованих на крадіжку даних із пристрою. Решта 4% — атаки з фізичним доступом та експлойти нульового дня, проти яких ефективна біометрична прив'язка.
Часті запитання
iOS Keychain — зашифрована БД для зберігання паролів, ключів і сертифікатів із контролем доступу через ACL. Android Keystore — криптографічний провайдер, який генерує та зберігає ключі в ізольованому середовищі (TEE/StrongBox) і не дозволяє витягти приватний ключ.
EncryptedSharedPreferences використовує AES-256 GCM для шифрування значень та AES-256 SIV для шифрування ключів. Основний ключ зберігається в Android Keystore, забезпечуючи дворівневий захист. Додатково використовується HMAC-SHA256 для перевірки цілісності.
Так, HTTPS захищає дані лише в каналі передачі. На пристрої дані зберігаються у відкритому вигляді після дешифрування. Якщо зловмисник отримає фізичний доступ до пристрою або встановить шкідливе ПЗ, HTTPS не захистить збережені дані. Завжди шифруйте дані на рівні зберігання.
Використовуйте Android Keystore із прапорцем setUnlockedDeviceRequired(true), який блокує доступ до ключів на рутованих пристроях. Додатково перевіряйте цілісність через Play Integrity API і за відхилення від еталонних значень очищайте всі секрети зі сховища.
Ні, UserDefaults зберігає дані у відкритому вигляді в plist-файлі всередині пісочниці. Будь-який застосунок з інструментами реверсинжинірингу (через резервну копію або джейлбрейк) може прочитати токени. Тільки Keychain — єдине безпечне місце для зберігання секретів на iOS.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також