API access tokens are the key to unlocking the power of various services for your mobile and web applications. But with this power comes the need for security to prevent unauthorized access to sensitive information.
In this article, we will dive into the technique of securing your app's data using Encrypted Shared Preferences of the Jetpack security library.
By the end of this article, you will have a solid understanding of how to safeguard your data in your Android applications and keep your user's data protected using encrypted shared preferences.
Encrypted SharedPreferences
Encrypted shared preference Wraps the SharedPreferences class and automatically encrypts keys and values using a two-scheme method: Keys are encrypted using a deterministic encryption algorithm such that the key can be encrypted and properly looked up. Values are encrypted using AES-256 GCM and are non-deterministic
Include the library in your project
To use the Security library, add the following dependencies, as appropriate, to your app module's build.gradle
file:
dependencies {
// security
implementation "androidx.security:security-crypto:1.0.0-alpha02"
}
Show me the code!
To demonstrate encrypted shared preferences, we'll create a helper class with two functions saveData
and getData
which as the name suggests, will be used to save and get data in a secure way.
Saving Data
private val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
fun saveData(context: Context, key: String, data: String) {
// Initialize/open an instance of EncryptedSharedPreferences
val sharedPreferences = EncryptedSharedPreferences.create(
// passing a file name to share a preferences
FILE_NAME,
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
sharedPreferences.edit().putString(key, data).apply()
}
In the snippet above, We start by initializing the android Keystore class which gives us access to a master key alias we'll be using to initialize an instance of the EncryptedSharedPreferences object.
On initializing the EncryptedSharedPreferences, we can then save our data as we normally would using the sharedPreferences edit()
and apply()
method
Retrieving Data
fun getData(context: Context, key: String): String? {
// Initialize/open an instance of EncryptedSharedPreferences on below line.
val sharedPreferences = EncryptedSharedPreferences.create(
// passing a file name to share a preferences
FILE_NAME,
masterKeyAlias,
context,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
//return the value or an empty string if it's null
return sharedPreferences.getString(key, "")
}
Again, we initialize an instance of the EncryptedSharedPreferences object using the master key alias we created earlier and passing in the name of the key value we want to retrieve.
We can use the functions from our mainActivity.kt
file or anywhere in our application like this:
And our complete sharedPreferencesHelper.kt
file should look like this:
After running the code we should see:
The username is Astrocoder and the access token is MY_ACCESS_TOKEN
printed in the logcat.
You can also check the emulator's data storage to see the encrypted My_file_name.xml
file and its content, just like in the image below
Conclusion
The Jetpack team has made it really easy to securely store and retrieve sensitive data in our apps with EncryptedSharedPreferences; Here are some of the advantages of using it:
It uses Android keystore to automatically remove the pain of having to achieve the same thing using other methods of encryption
Every data we feed it is encrypted, including the key names used to access the shared preference values, as we can see in the image above, making it a lot harder for any attacker to know what data to attack
That's a wrap!!! feel free to reach out to me on any of my social media accounts should you have any questions.
You can find the complete code to this example on GitHub, here
Thank you for reading! Cheers!!!