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