The common location where
SharedPreferences are stored in Android apps is:
User with root privileges can navigate to this location and can change its values.Need of protecting it is of much importance.
In how many ways we can encrypt whole
shared_pref's xml file?
We all know that we can encrypt and save data in
shared_pref's xml file, but that’s not only 100% safe, so need to encrypt whole file with a key. Need help in knowing various ways to encrypt whole
xml file. This is generic question, various encryption methods discussed as answers here can be helpful to all developers in securing apps.
Android has released a security library with EncryptedSharedPreferences in their Jitpack library.
Min API is 23 (6.0+)
String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC); SharedPreferences sharedPreferences = EncryptedSharedPreferences.create( "secret_shared_prefs", masterKeyAlias, context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ); // use the shared preferences and editor as you normally would SharedPreferences.Editor editor = sharedPreferences.edit();
Google has released
EncryptedSharedPreferences as part of it’s androidx, I believe this should be the preferable way of encrypting the preferences.
You should encrypt your data and write to SharedPreferences. When you want get this data then you should decrypt from SharedPreferences. you need the following helper class for this
then you can write in SharedPreferences by encrypting your data as follows
you can finally read from SharedPreferences data in the following way. This way, sensitive information will be safer while kept on the hardware level in the phone
Base64 is NOT encryption! Don’t use it! Yes ‘root’ users can access that data. One thing you can do is use AES to encrypt either that data or use a single NoSQL database file and encrypt that file. When the app opens, you decrypt the database and use that to store info or encrypt all files independently.
Complete answer (api level 23+). First you need crypto from androidx.
Care : there is a significant performance difference between SharedPreferences and EncryptedSharedPreferences.
You should notice that EncryptedSharedPreferences.create(…) is not so fast so you should have to store one instance at all.
Then you have to use this to retrieve EncryptedSharedPreferences.
The you just have to use preference like the “standard way”. To save it :
To retrieve preference value.
Kotlin example for dual purpose encrypted & unencrypted shared preferences using anrdoidx’s security-crypto library (min API 23).
- Decent introduction to EncryptedSharedPreferences: garageprojects.tech/
I use Dagger2 to inject this as a @Singleton where needed.
Use the @Name annotation in your Dagger Modules to differentiate between the SharedPreferences instances and you can have 2 separate .xml files (1 encrypted, 1 unencrypted) to read/write to/from.
- Decent introduction to Dagger2: codinginflow.com
- Dagger Module & field injection example for the following code: stackoverflow.com
Add to dependenies in build.gradle:
An alternative option to using Dagger2 to inject as a @Singleton could be to:
Then just call from where ever