Recently while developing an android app, we were required to save some sensitive information persistently in shared preferences. The best practices says not to save such information on device but sometimes you gotta do.

Shared Preferences

The SharedPreferences class provides a general framework that allows you to save and retrieve persistent key-value pairs of primitive data types.

Unsecure Shared Preferences

Shared preferences provides a simple way to persistently store key value pairs. But if someone gets root access to device then it is trivial to read/write the information stored in it. So anything written as plaintext will we open to the world to see and write. Thats a big NO NO.

Encrypt the data in Shared Preferences

The first thing which come to our mind is to encrypt the data to be saved. Looks like problem solved. Yeah!!!. But wait, where to hide the encryption key. Now again we got into chicken and egg situation. Now the security again depends upon safeguarding the encryption key.

Source: http://media.giphy.com/media/kgmXZsZ1ldinu/giphy.gif

Unsafe Encryption Key

If the encryption key is saved somewhere in the source code then the apk could be decompiled and the key could be found out. Products like ApkTools , dex2jar have made it very easy to do so.

So how to safeguard the encryption key.

source : http://gifake.net/post/9785897330/spongebob-squarepants

Obfuscation

So one solution is to obfuscate the key in the source code, such that it becomes difficult for reverse engineer. Some obfuscation tecniques are discussed here http://stackoverflow.com/questions/14570989/best-practice-for-storing-private-api-keys-in-android and http://fuzion24.github.io/android/obfuscation/ndk/llvm/o-llvm/2014/07/27/android-obfuscation-o-llvm-ndk/ and many other places.

Some paid obfuscation tools exist, One by Eric P.F. Lafortune (Maker of proguard) called dexguard. It has inbuild methods like ‘encryptstring’ and ‘encryptclasses’ which obfuscate strings and classes respectively.

Other than these one can also use ndk to write c file which contain string and return the string using JNI.

Not fool proof

Mixing and matching the above techniques would make reverse engineering difficult but not fool proof.

The solution: Android Keystore System

The Android Keystore system lets you store private keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the private key material remaining non-exportable.

So this is something what we were searching about. One problem though, It was introduced in API level 18. But guess what, our app was ‘minSdkVersion 18’ hell yeah. If android keystore system is unbreakable then we can breathe free.

A.O.S.P. even has a sample using the Android Keystore System called Vault.

At the end we were able to find a good solution by understanding the source code of Vault and android developers blogpost on security http://android-developers.blogspot.in/2013/02/using-cryptography-to-store-credentials.html

Talk is cheap. Show me the code.

Not being an expert on encryption and cryptography, we thought it would be a good idea to open-source our code for the developer community. We welcome if anyone finds any issues and suggest corrections.

Our solution resides here https://github.com/ophio/secure-preferences .

Update

Anything is not so easy and straightforward in the world of androids. There are some caveates in the Android Keystore Provider. It is forgetful so losses its values in some OS versions when the lock type for phone changes.

Though, if you are OK with loosing the encrypted data when lock changes then there is no problem, as was the case in the application I was developing.

Update 2

Throught the github issue tracker I have been notified of 2 big issues in the repository https://github.com/ophio/secure-preferences/issues/19 and https://github.com/ophio/secure-preferences/issues/13 . Any help with these would be praiseworthy.