Securing Shared Preferences with Third Party Libraries
In one of the previous articles, we have seen how developers implement Shared Preferences in Android applications. We have also seen how one can compromise the sensitive data stored in Shared Preferences if proper security controls are not enforced. In this article, we shall discuss how we can secure Shared Preferences data in Android using a third party crypto library known as “Secure Preferences”. Though this library doesn’t provide a 100% guarantee that our app will be secure, in case the device is rooted, we can make the app relatively more secure when compared to regular Shared Preferences.
“Secure Preferences” is an encryption wrapper that wraps the Shared Preferences in Android. It encrypts the Shared Prefereces data being stored in XML files. It is free and open source.
This article walks you through the step by step procedure of how developers can use the “Secure Preferences” library to protect data stored in Shared Preferences.
Implementing Secure Preferences in Android
Download the “Secure Preferences” library which is available by filling out the form: [download]
Create a new Application project in Eclipse to implement the “Secure Preferences” library in it.
We can now add the library downloaded in step 1 to our new Android project so that we can use the library. This is similar to the process of linking any other library to our Android project. If you are not sure about how to do it, one of the simple ways to do it is to right click and go to properties, then check “is library” option to make it a library and then link it to your application.
To use “Secure Preferences” in our application, we need to initialize the Secure Preferences object with the current class context.
Now, just like the regular Shared Preferences application, create an “Editor” object to insert data into the XML file.
As we can see in the above figure, we are getting data from the user and inserting it into the XML file using the Editor object and putString() method.
To retrieve data from the XML file, we can simply use the getString() method with the necessary arguments.
The above code snippet describes that the code is fetching the value of the key “PASSWORD” and displaying it in a textview.
This is how we can use the “Secure Preferences” library in our Android projects.
Now, let’s try to understand what happens when we use Secure Preferences and how it reduces the chances of attackers compromising Shared Preferences data.
The sample code and APK file we used can be downloaded from downloads section.
The application we developed in this article has an XML layout with one EditText, where we can enter the secret to be stored, and two buttons, one to save data another one to retrieve data. Finally, we have a textview to display the text being retrieved from the XML file. This is shown in the screenshot below.
When we enter some data into the text box and hit the “Encrypt and Save” button, code displayed in Step 5 in the previous section will be executed. This encrypts the data being entered by the user.
When we hit “Decrypt and Display” button, it goes ahead and decrypts the data stored in Shared Preferences.
Now, let’s examine how the data is being stored in an XML file to understand why it is difficult for an attacker to compromise the data in Shared Preferences wrapped with Secure Preferences.
As we know, it creates an XML file to store data. So let’s pull it on to the local machine using the following command.
adb pull /data/data/com.isi.secureprefs/shared_prefs/com.isi.secureprefs_preferences.xml
Now, we can look at the contents of the file using the “cat” command on the terminal as shown below.
The above figure shows the data being stored inside the XML file. As we can see, it is in unreadable format.
How does “SecurePreferences” work?
The Secure Preferences library uses the AES algorithm for its encryption. It pseudo randomly generates an encryption key when we instantiate “Secure Preferences” for the first time in the application. This key encrypts the key-value pairs and then the encrypted data will be encoded using the base64 algorithm before storing in an XML file. Since AES is a symmetric algorithm, the same key will be used to decrypt all the encrypted key-value pairs.
In this article we have seen how we can encrypt the key-value pairs being stored via Shared Preferences. This greatly increases the security of the data being stored in the device. But if the device is rooted, it is not ideal. So, it is always suggested that using Password Based Encryption is a better way, since we can generate the encryption key at runtime using the password provided by the user.