Encrypt and persist Parcelable objects on disk in Android using DiskLruCache and Facebook Conceal

You can use Jake Whartons’ DiskLruCache and Facebook Conceal to encrypt Parcelable objects stored on disk.

Why?

There are a few reasons I can think off:

  • Most obvious: The data in your app is sensitive and you don’t want to store it unencrypted on internal or external storage.
  • You don’t want to reinvent the wheel by writing your own disk I/O and having to deal with doing it asynchronously, keeping it performant, yada yada, yada.
  • You want to take advantage of DiskLruCache’ other features, such as versioning stored objects (perhaps to allow you to provide a cool undo feature).
  • Bitmaps are Parcelable, this means you can cache / store bitmaps and no one can see what it is.

How?

Initially I had modified the code in DiskLruCache directly to support this, however, I found a better and simpler solution which I have shared below.

Step 1: Integrate Facebook Conceal into your project

You can download the jars and native binaries here. Add the Conceal jar and the Android jar to your app/libs directory. Add the binaries to app/src/main/jniLibs directory.

Next, add these rules to your proguard configuration.

# Facebook Conceal
# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.crypto.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.crypto.proguard.annotations.KeepGettersAndSetters

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.crypto.proguard.annotations.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.crypto.proguard.annotations.DoNotStrip *;
}

-keepclassmembers @com.facebook.crypto.proguard.annotations.KeepGettersAndSetters class * {
void set*(***);
*** get*();
}

Step 2: Include DiskLruCache

Simply add the following dependency.

compile 'com.jakewharton:disklrucache:2.0.2'

Step 3: Create a wrapper around DiskLruCache to persist Parcelable

I initially got this code for this from Vald Sumstov’s gist “Cache your data with parcelable and disklrucache”. I did however modify it slightly. In my implementations, there is an Abstract class that I extend to create singletons, for storing on disk (long term) and for persisting as cache. The main difference between the 2 ParcelDiskStore and ParcelDiskCache is what directory they store the files in. If you store things in the cache directory, they can be purged by the system any time, if you store them in the file system or on an external disk, they will remain there till you run out of space. This is why the disk store has 50 MB allocated to it, since disk cache only has 5 MB allocated (you can choose whatever numbers you like). There are put and get methods in ParcelDiskStore and ParcelDiskCache that you can use to store and get objects.

The current implementations doesn't use versioning. This is because I didn't need it. You can look at the unit tests for DiskLruCache to get an idea of how to implement this.

Using this with Volley

In order to use this with Volley, you have to start with creating a wrapper around DiskLruCache which enables you to use DiskLruCache with Volley. An implementation is provided here. You then have to override their read and write methods and plug-in facebook conceal on the input and output streams much like I have in my abstract class.

Finally

If you've made it this far, we should hang out. Check out my other articles on Medium and feel free to follow me on Medium, Google+, Twitter or LinkedIn.