[Перевод] Зашифрованные предпочтения в Андроид
Добрый день. Меня зовут Дмитрий и я являюсь преподавателем базового курса «Android разработчик» в Otus. Сегодня я решил поделиться переводом статьи, которую считаю интересной и думаю, что она может быть полезной для многих читателей нашего блога.
Хранить данные в SharedPreferences очень быстро и удобно. Злоумышленникам также легко взглянуть на данные, хранящиеся в SharedPreferences…так что будьте осторожны с тем, что вы там поместили, и, возможно, придется задуматься о том, как хранить данные в зашифрованном формате.
Для небольших объемов данных, которые не оправдывают использование механизма БД, такого как SqlCipher, наши возможности были ограничены:
- Собственные методы шифрования (если вы знаете, что делаете)
- Готовые решения, такие как Secure-preferences, другие Secure-preferences, Armadillo и т.д.
- Борьба с самыми странными проблемами жизненного цикла системы Android Keystore в каждой версии Android
Это работало раньше, но теперь у нас есть правильное и официальное решение.
Хотя это все еще альфа, она какое-то время работала хорошо, когда я использовал ее в своих проектах. Использование EncryptedSharedPreferences приветствуется (или же вы можете использовать его), для всех своих с min-sdk 23+.
Давайте рассмотрим пример того, как его использовать:
Пример EncryptedSharedPreferences
Минимальный SDK
На сегодняшний день 23 (Android 6.0)
minSdkVersion 23
Добавьте зависимости
implementation "androidx.security:security-crypto:1.0.0-alpha02"
Инициализировать / открыть
Просто создайте или извлеките мастер-ключ из хранилища ключей Android и используйте его для инициализации / открытия экземпляра EncryptedSharedPreferences:
// Шаг 1: Создать или получить мастер-ключ для шифрования / дешифрования
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
// Шаг 2. Инициализируйте / создайте экземпляр EncryptedSharedPreferences
val sharedPreferences = EncryptedSharedPreferences.create(
"PreferencesFilename",
masterKeyAlias,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
Сохранить записи
Сохраните данные, как вы всегда делали с SharedPreferences:
// Шаг 3. Сохраните данные в EncryptedSharedPreferences
sharedPreferences.edit()
.putString("DATA", saveText.text.toString())
.apply()
Читать записи
Читайте данные, как вы всегда делали с SharedPreferences:
// Шаг 3: Считайте данные из EncryptedSharedPreferences
val value = sharedPreferences.getString("DATA", "")
Действительно ли настройки зашифрованы?
Да, и действительно довольно хорошо зашифрованы.
Скажем, я поместил значение akaita
в SharedPreferences
. Вот как будет выглядеть файл:
Если я добавлю значение akaita
в EncryptedSharedPreferences
, я получу что-то совсем другое:
Более того, зашифрованный файл будет меняться каждый раз, когда мы сохраняем, что затрудняет доступ к нему.
Большое предостережение: производительность
Существует значительная разница в производительности между SharedPreferences и EncryptedSharedPreferences.
Вы можете проверить сами, используя мой пример кода или просто скачав пример приложения из Play Store. Я сам провожу несколько тестов на реальном устройстве, получая следующие результаты:
EncryptedSharedPreferences в сравнении с SharedPreferences
График «EncryptedSharedPreferences в сравнении с SharedPreferences»
Заключение
EncryptedSharedPreferences является надежным и очень простым решением для Android 6.0 и выше.
Он имеет два больших плюса:
- нам не нужно ничего кодировать в нашем коде. Он просто использует Android Keystore для нас, избавляя себя от необходимости справляться с этим
- пользователю не нужно устанавливать экран блокировки. EncryptedSharedPreferences будет работать так же хорошо, без блокировки экрана
Это почти полная замена SharedPreferences. Просто убедитесь, что инициализация / открытие EncryptedSharedPreferences не влияет негативно на ваших пользователей.
Это решение определенно останется. Я использую это в любом подходящем сценарии. Теперь я просто хочу сказать, что ребята из Android улучшат его производительность, так что нам можно беспокоиться еще меньше:)
Пример приложения
Просто, чтобы было проще протестировать и убедиться, что все хорошо связано, я создал и приложение для вас. Загрузите его или скомпилируйте и попробуйте!
https://github.com/akaita/encryptedsharedpreferences-example
Ставьте плюс, если считаете статью полезной, а на любые вопросы буду рад ответить в комментариях.