Securing SharedPreferences data

Android provides a simple framework for app developers to persistently store key-value pairs of primitive datatypes. This recipe illustrates a practical use of a pseudorandomly generated secret key and demonstrates the use of Secure-Preferences . It is an open source library that wraps the default Android SharedPreferences to encrypt the key-value pairs for protecting them against attackers. Secure-Preferences is compatible with Android 2.1+, and is licensed with Apache 2.0; hence, it is suitable for commercial development.

I should add that I'm the co-creator and maintainer of the Secure-Preferences library. A good alternative to Secure-Preferences is a library called Cwac-prefs that is backed by SQLCipher (covered in a later recipe).

Getting ready

Let's add the Secure-Preferences library.

  1. Download or clone Secure-Preferences from GitHub at https://github.com/scottyab/secure-preferences.

    The Secure-Preferences repository contains an Android library project and a sample project.

  2. Link the library to your Android project as you would normally do.

How to do it...

Let's get started.

  1. Simply initialize the SecurePreferences object with Android context:
    SharedPreferences prefs = SecurePreferences(context);
    
    Editor edit = prefs.edit();
    edit.putString("pref_fav_book", "androidsecuritycookbook");
    edit.apply();
  2. The following are several helper methods that you could add to your application to retrieve an instance of the (secure) preferences object in your application object:
    private SharedPreferences mPrefs;
    public final SharedPreferences getSharedPrefs() {
        if (null == mPrefs) {
          mPrefs = new SecurePreferences(YourApplication.this);
        }
        return mPrefs;
      }

    Here, YourApplication.this is a reference to your application object.

  3. Then ideally, in a base application component such as BaseActivity, BaseFragment, or BaseService, you can include the following to retrieve an instance of the (secure) preferences object:
    private SharedPreferences mPrefs;
    protected final SharedPreferences getSharedPrefs() {
        if (null == mPrefs) {
          mPrefs = YourApplication.getInstance().getSharedPrefs();
        }
        return mPrefs;
      }

How it works...

The Secure-Preferences library implements the SharedPreferences interface; therefore, no code changes are needed to interact with it in comparison to the default SharedPreferences.

Standard SharedPreferences keys and values are stored in a simple XML file and Secure-Preferences uses the same storage mechanism; except that the keys and values are transparently encrypted using an AES symmetric key. The cipher text of keys and values are encoded with base64 encoding before writing to the file.

If you examine the following SharedPreference XML file; it shows without and with the Secure-Preferences library. You'll see the file from the Secure-Preferences library is a collection of seemingly random entries that give no clue to their purpose.

  • A standard SharedPreferences XML file:
    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <map>
    <int name="timeout " value="500" />
    <boolean name="is_logged_in" value="true" />
    <string name="pref_fav_book">androidsecuritycookbook</string>
    </map>
  • A SharedPreferences XML file using Secure-Preferences library:
    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <map>
    <string name="MIIEpQIBAAKCAQEAyb6BkBms39I7imXMO0UW1EDJsbGNs">
    HhiXTk3JRgAMuK0wosHLLfaVvRUuT3ICK
    </string>
    <string name="TuwbBU0IrAyL9znGBJ87uEi7pW0FwYwX8SZiiKnD2VZ7"> va6l7hf5imdM+P3KA3Jk5OZwFj1/Ed2
    </string>
    <string name="8lqCQqn73Uo84Rj">k73tlfVNYsPshll19ztma7U">
    tEcsr41t5orGWT9/pqJrMC5x503cc=
    </string>
    </map>

The first time SecurePreferences is instantiated, an AES encryption key is generated and stored. This key is used to encrypt/decrypt all future keys/values that are saved via the standard SharedPreferences interface.

The shared preference file is created with Context.MODE_PRIVATE that enforces app sandbox security and ensures that only your app has access. However, in the case of rooted devices, sandbox security cannot be relied upon. More correctly, Secure-Preferences is obfuscating the preferences; therefore, this should not be considered as bulletproof security. Instead, view it as a quick win for incrementally making an Android app more secure. For instance, it will stop users on rooted devices easily modifying your app's SharedPreferences.

Secure-Preferences could be further enhanced to generate the key based on the user input password using a technique called password-based encryption (PBE ), which is covered in the next chapter.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.200.76