Добрый день. Меня зовут Дмитрий и я являюсь преподавателем базового курса «Android разработчик» в Otus. Сегодня я решил поделиться переводом статьи, которую считаю интересной и думаю, что она может быть полезной для многих читателей нашего блога.
Хранить данные в SharedPreferences очень быстро и удобно. Злоумышленникам также легко взглянуть на данные, хранящиеся в SharedPreferences …так что будьте осторожны с тем, что вы там поместили, и, возможно, придется задуматься о том, как хранить данные в зашифрованном формате.
Для небольших объемов данных, которые не оправдывают использование механизма БД, такого как SqlCipher, наши возможности были ограничены:
Это работало раньше, но теперь у нас есть правильное и официальное решение.
Хотя это все еще альфа, она какое-то время работала хорошо, когда я использовал ее в своих проектах. Использование EncryptedSharedPreferences приветствуется (или же вы можете использовать его), для всех своих с min-sdk 23+.
Давайте рассмотрим пример того, как его использовать:
На сегодняшний день 23 (Android 6.0)
Просто создайте или извлеките мастер-ключ из хранилища ключей Android и используйте его для инициализации / открытия экземпляра EncryptedSharedPreferences:
Сохраните данные, как вы всегда делали с SharedPreferences:
Читайте данные, как вы всегда делали с SharedPreferences:
Да, и действительно довольно хорошо зашифрованы.
Скажем, я поместил значение
Если я добавлю значение
Более того, зашифрованный файл будет меняться каждый раз, когда мы сохраняем, что затрудняет доступ к нему.
Существует значительная разница в производительности между SharedPreferences и EncryptedSharedPreferences.
Вы можете проверить сами, используя мой пример кода или просто скачав пример приложения из Play Store. Я сам провожу несколько тестов на реальном устройстве, получая следующие результаты:
EncryptedSharedPreferences в сравнении с SharedPreferences
График «EncryptedSharedPreferences в сравнении с SharedPreferences»
EncryptedSharedPreferences является надежным и очень простым решением для Android 6.0 и выше.
Он имеет два больших плюса:
Это почти полная замена SharedPreferences. Просто убедитесь, что инициализация / открытие EncryptedSharedPreferences не влияет негативно на ваших пользователей.
Это решение определенно останется. Я использую это в любом подходящем сценарии. Теперь я просто хочу сказать, что ребята из Android улучшат его производительность, так что нам можно беспокоиться еще меньше :)
Просто, чтобы было проще протестировать и убедиться, что все хорошо связано, я создал и приложение для вас. Загрузите его или скомпилируйте и попробуйте!
https://github.com/akaita/encryptedsharedpreferences-example
Ставьте плюс, если считаете статью полезной, а на любые вопросы буду рад ответить в комментариях.
Хранить данные в 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
. Вот как будет выглядеть файл:<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="DATA">akaita</string>
</map>
Если я добавлю значение
akaita
в EncryptedSharedPreferences
, я получу что-то совсем другое:<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="AVz2qCVxm1KudCCJKYuxuoaAXoPeWKjG0w==">ASnO9uni11t3m9sNgDJbiYllL/tE+i99TYKfQ0h8XV6AUN0O3rBxBsMmcpw2DCY=</string>
<string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001</string>
<string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001</string>
</map>
Более того, зашифрованный файл будет меняться каждый раз, когда мы сохраняем, что затрудняет доступ к нему.
Большое предостережение: производительность
Существует значительная разница в производительности между SharedPreferences и EncryptedSharedPreferences.
Вы можете проверить сами, используя мой пример кода или просто скачав пример приложения из Play Store. Я сам провожу несколько тестов на реальном устройстве, получая следующие результаты:
EncryptedSharedPreferences в сравнении с SharedPreferences
График «EncryptedSharedPreferences в сравнении с SharedPreferences»
Заключение
EncryptedSharedPreferences является надежным и очень простым решением для Android 6.0 и выше.
Он имеет два больших плюса:
- нам не нужно ничего кодировать в нашем коде. Он просто использует Android Keystore для нас, избавляя себя от необходимости справляться с этим
- пользователю не нужно устанавливать экран блокировки. EncryptedSharedPreferences будет работать так же хорошо, без блокировки экрана
Это почти полная замена SharedPreferences. Просто убедитесь, что инициализация / открытие EncryptedSharedPreferences не влияет негативно на ваших пользователей.
Это решение определенно останется. Я использую это в любом подходящем сценарии. Теперь я просто хочу сказать, что ребята из Android улучшат его производительность, так что нам можно беспокоиться еще меньше :)
Пример приложения
Просто, чтобы было проще протестировать и убедиться, что все хорошо связано, я создал и приложение для вас. Загрузите его или скомпилируйте и попробуйте!
https://github.com/akaita/encryptedsharedpreferences-example
Ставьте плюс, если считаете статью полезной, а на любые вопросы буду рад ответить в комментариях.