Why Should You Encrypt SharedPreferences?
Recently, in one client project, a vulnerability was discovered: the authorization token was stored in plaintext. After a breach via ADB (debugging was enabled in the release build), attackers gained access to 10,000 tokens in a couple of minutes. We rewrote storage to EncryptedSharedPreferences—this closed the attack vector completely. 99% of similar incidents involve unencrypted data on the device.
Tokens, settings, API keys—all of this must be locked down. Even if the app does not use biometrics, encryption protects from physical access, backups, and malware. We guarantee data confidentiality through two-level encryption from Jetpack Security. Over 5+ years, we have implemented protection in 20+ projects—zero incidents. A security audit will show that your app complies with OWASP Mobile Top 10.
How Does EncryptedSharedPreferences Work?
Initialization requires a master key from the Android Keystore. Google Tink provides cryptographic strength: keys are encrypted with AES256-SIV (deterministic encryption for lookup), values with AES256-GCM. The master key is stored in hardware-backed storage and is device-bound.
val masterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .setUserAuthenticationRequired(false) // true if biometrics needed .build() val prefs = EncryptedSharedPreferences.create( context, "secure_prefs", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) The API is identical to regular SharedPreferences—putString, getString, edit().apply(). No additional code required. However, there are nuances: getAll() is not supported, and the file is device-bound.
| Metric | Plain SharedPreferences | EncryptedSharedPreferences |
|---|---|---|
| Security | Data in plaintext | Data encrypted (AES256) |
| Performance | ~0.1 ms per read | ~2–5 ms per read |
| Backup | Fully copied | Requires exclusion from backup_rules.xml |
What Exactly Is Encrypted and How?
| Data Type | Before Encryption | After Encryption |
|---|---|---|
| Settings | <string name="theme">dark</string> |
base64:... (AES256-SIV) |
| Tokens | <string name="token">eyJ...J9</string> |
base64:... (AES256-GCM) |
The Secure Prefs file contains an unreadable blob. Even with physical device access, data cannot be decrypted without the master key from Keystore. In our experience, this approach closes 99% of threats for storing session data.
How to Migrate Without Data Loss?
Migration from plain SharedPreferences is a typical task we complete in 4–8 hours. Step-by-step plan:
- Read all keys from the old file using
getAll()(exception for migration; afterwards rewrite to explicit reads). - Write each key into the new encrypted file using
edit().putString(). - Delete the old file
context.deleteSharedPreferences("old_name"). - Replace all
getSharedPreferencescalls in code withEncryptedSharedPreferences.create. - Add
android:fullBackupContent="@xml/backup_rules"and exclude the encrypted file from Auto Backup.
Important: getAll() is not supported in EncryptedSharedPreferences in production—after migration, rewrite iteration to explicit keys.
What Are the Pitfalls When Using EncryptedSharedPreferences?
If the device is rebooted and biometrics are enabled, background workers may not get access to the data. Solution: explicitly set setUserAuthenticationRequired(false) and use the DEVICE_CREDENTIAL scheme. This guarantees access after reboot.
The preferences file is bound to the device's Keystore. It cannot be copied to another device—this protects against exfiltration. In early alpha versions of Jetpack Security (e.g., 1.1.0-alpha02), there was a bug causing data loss under certain conditions—we have accounted for this and always use stable releases.
When the device is reset or the PIN is changed, the master key may become unavailable. In that case, encrypted data is lost irrevocably. We recommend always having a backup plan—for instance, store refresh tokens separately or use cloud backup.
When Is EncryptedSharedPreferences Not Enough?
If data is needed in a background worker without the user on screen and the device is rebooted, you need direct control over Android Keystore or use EncryptedFile for large volumes. For streaming file writes (images, logs), Jetpack Security EncryptedFile is better suited. It is not limited by size and supports streaming encryption.
What Is Included in the Work and Timelines
- Consultation on data storage architecture.
- Master key setup (biometrics or without).
- Migration of all existing SharedPreferences, accounting for
getAll()andbackup_rules.xml. - Testing on API 23+ (over 30 devices).
- Documentation and maintenance recommendations.
- One month post-deployment support.
Timelines: simple replacement—4–8 hours with testing. If Auto Backup and complex configuration are involved, add a few more hours. The cost is calculated individually after analysis of your project. Contact us to get an estimate.
We have implemented data protection for 20+ Android applications—zero incidents. Get a security assessment for your app—the evaluation takes one day. Contact us to protect your users' data.







