← Назад к вопросам

Какие знаешь способы шифрования базы данных?

2.0 Middle🔥 131 комментариев
#Производительность и оптимизация#Работа с данными

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы шифрования базы данных в Android

В Android-разработке защита локальных баз данных — критически важная задача, особенно при хранении персональных данных пользователей. Я выделяю несколько основных подходов, которые различаются по уровню безопасности, производительности и сложности реализации.

1. Шифрование на уровне файла БД с SQLCipher

SQLCipher — это наиболее популярное и надёжное решение, предоставляющее прозрачное шифрование всей базы данных SQLite на уровне файла. Это расширение SQLite с открытым исходным кодом, использующее библиотеку OpenSSL.

Ключевые особенности:

  • Полное шифрование: Шифруются все данные, включая метаданные и структуру таблиц.
  • Прозрачность: После установки ключа работа с БД идёт через стандартный SQLiteOpenHelper, шифрование/дешифрование происходит "под капотом".
  • Алгоритмы: Использует AES-256 в режиме CBC или GCM.
  • Интеграция: Простая интеграция через Gradle.

Пример реализации:

implementation 'net.zetetic:android-database-sqlcipher:4.5.3'

// Открытие зашифрованной базы данных
val passphrase = "supersecret".toCharArray()
val database = SQLiteDatabase.openOrCreateDatabase(
    databaseFile,
    passphrase,
    null,
    SQLiteDatabaseHook()
)

// Через SupportFactory (рекомендуемый способ)
val supportFactory = SupportFactory(passphrase)
val database = Room.databaseBuilder(context, AppDatabase::class.java, "encrypted.db")
    .openHelperFactory(supportFactory) // Ключевая строка для Room
    .build()

Недостатки: Небольшое снижение производительности (10-15%) и увеличение размера APK.

2. Шифрование на уровне приложения с Room и Android Keystore

Этот подход предполагает шифрование отдельных полей или преобразование данных перед записью в БД, используя криптографические примитивы Android и безопасное хранение ключей в Android Keystore.

Ключевые особенности:

  • Гибкость: Можно шифровать только конфиденциальные поля.
  • Безопасное хранение ключей: Ключи хранятся в Trusted Execution Environment (TEE) или Secure Element (SE).
  • Type Converters в Room: Удобно реализуется через @TypeConverter.

Пример реализации с AES и Keystore:

// Генерация и хранение ключа в Keystore
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
val keyGenSpec = KeyGenParameterSpec.Builder(
    "my_db_key",
    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
    .setUserAuthenticationRequired(true) // Опционально: требовать биометрию
    .build()
keyGenerator.init(keyGenSpec)
keyGenerator.generateKey()

// TypeConverter для Room
class Converters {
    @TypeConverter
    fun fromEncryptedString(encryptedData: ByteArray?): String? {
        if (encryptedData == null) return null
        val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
        // ... инициализация cipher для дешифрования ключом из Keystore
        return String(cipher.doFinal(encryptedData))
    }

    @TypeConverter
    fun stringToEncryptedString(data: String?): ByteArray? {
        if (data == null) return null
        val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
        // ... инициализация cipher для шифрования ключом из Keystore
        return cipher.doFinal(data.toByteArray())
    }
}

3. Шифрование на уровне файловой системы (FBE)

File-Based Encryption (FBE) — это системная функция Android, начиная с версии 7.0. Она прозрачно шифрует файлы на диске с использованием уникального ключа, привязанного к блокировке экрана пользователя.

Как использовать:

  • Файлы, созданные приложением, когда устройство заблокировано, могут быть помечены как ENCRYPTED_MODE_LOCAL. Они будут доступны только после первой разблокировки устройства.
  • Используется автоматически для всех приложений, но разработчик может управлять доступностью файлов через константы Context.MODE_PRIVATE, Context.MODE_WORLD_READABLE (устарело) и флаги в openFileOutput().

Ключевой момент: Этот метод защищает данные на потерянном/украденном устройстве, но не обеспечивает защиту от root-доступа или других приложений на разблокированном устройстве. Его стоит рассматривать как дополнительный уровень защиты, а не как полноценное шифрование БД.

4. Гибридные подходы

На практике часто комбинируют методы для баланса безопасности и производительности:

  1. SQLCipher + Android Keystore: Использовать SQLCipher для шифрования файла БД, а ключ-пароль для SQLCipher хранить в Android Keystore. Это защищает ключ даже на устройствах с root-правами.

    // Получение ключа из Keystore для использования в SQLCipher
    val keyStore = KeyStore.getInstance("AndroidKeyStore")
    keyStore.load(null)
    val secretKeyEntry = keyStore.getEntry("sqlcipher_key", null) as KeyStore.SecretKeyEntry
    val passphrase = secretKeyEntry.secretKey.encoded // Используется для инициализации SupportFactory
    
  2. Выборочное шифрование полей в Room + FBE: Шифровать только самые чувствительные данные (пароли, токены) через TypeConverter, полагаясь на FBE для защиты остальных данных БД.

Критерии выбора и лучшие практики

При выборе метода учитывайте:

  • Уровень угроз: Для финансовых и медицинских приложений обязателен SQLCipher или шифрование на уровне поля с Keystore.
  • Производительность: Полное шифрование БД (SQLCipher) снижает скорость операций. Для больших объёмов данных может потребоваться оптимизация.
  • Сложность: Шифрование на уровне поля даёт больше контроля, но увеличивает сложность кода и риск ошибок (неправильный выбор режима AES, неправильные IV).
  • Миграция: План миграции с незашифрованной БД на зашифрованную должен быть продуман заранее. SQLCipher предоставляет для этого API.
  • Хранение ключа: Никогда не храните ключи шифрования в виде plain text в коде, SharedPreferences или файлах. Используйте Android Keystore для генерации и хранения криптографических ключей. Для ключей, несовместимых с Keystore (например, паролей для SQLCipher), используйте дополнительное шифрование с помощью ключа из Keystore.

Рекомендация: Для большинства коммерческих приложений, работающих с персональными данными, оптимальным выбором является SQLCipher в связке с Android Keystore для хранения мастер-ключа. Этот подход обеспечивает военную степень защиты, приемлемую производительность и соответствует строгим требованиям стандартов безопасности, таких как GDPR и PCI DSS.

Какие знаешь способы шифрования базы данных? | PrepBro