Caching and storage are tricky problems for mobile developers because they directly impact performance and data usage on a mobile device. Caching helps developers speed up their apps and reduce network costs for the device owner by storing information directly on the phone for later access. However, internal storage capacity on Android phones is often limited, especially with lower to mid range phone models. A common solution for Android is to store some data on an expandable SD card to mitigate the storage cost. What many people don’t realize is that Android’s privacy model treats the SD card storage as a publicly accessible directory. This allows data to be read by any app (with the right permissions). Thus, external storage is normally not a good place to store private information.
We saw an opportunity to do things better and decided to encrypt the private data that we stored on the SD card so that it would not be accessible to other apps. To do this efficiently, we built Conceal, a set of Java APIs to perform cryptography on Android and make storage more secure and lightweight. We created Conceal to be small and faster than existing Java crypto libraries on Android while using memory responsibly.
Designing for Security
Conceal is not a general purpose crypto library. Unlike other libraries, which provide a wide range of encryption algorithms and options, Conceal prefers to abstract this choice and include sensible defaults. We think this makes sense because encryption can be very tricky to get right.
AES is the de facto standard for encryption; however, AES can only encrypt a small block at a time. Developers must choose a mode of AES to encrypt a large file, and selecting the right mode can be tricky. Many instances of vulnerabilities in apps that use encryption come from choosing insecure modes like AES-ECB, and many libraries ask developers to make this choice.
Encryption provides secrecy of data, but additional steps are necessary to prevent someone from tampering with the data. A common way of ensuring both secrecy and integrity of data is to encrypt it and then compute a Message Authentication Code (MAC) of the encrypted data using an algorithm like HMAC. We found that computing an HMAC takes significant time in the encryption of data, so in Conceal, we instead use AES-GCM which is an authenticated encryption algorithm that not only encrypts the data but also computes a MAC of the data at the same time.
Abstracting security details also allows us to deal with issues like known weaknesses in Android’s random number generator, without users having to worry about it. Specifically, Conceal provides default implementations of key management and stores the key in private SharedPreferences by default. It also performs authenticated versioning of the encryption libraries so that if we change the encryption algorithms we use in the future, we can retain both compatibility with previously encrypted data and resistance against cross version attacks.
Conceal doesn’t implement any crypto. Instead, it uses specific cryptographic algorithms from OpenSSL. OpenSSL’s crypto library is about 1MB when built for armv7. By using only the parts of OpenSSL we needed, we were able to reduce the size of OpenSSL to 85KB. We believe providing a smaller library will reduce the friction of adopting state of the art encryption algorithms, make it easier to handle different Android platform versions, and enable us to quickly incorporate fixes for any security vulnerabilities in OpenSSL as well.
In our open source release, we’re providing pre-built binaries for these crypto functions from OpenSSL so that everyone can build their own small OpenSSL binary with the functions required by Conceal.
Conceal provides an easy to use API, which you can find here: http://facebook.github.io/conceal/. To encrypt data, you simply pass an output stream and get back a wrapped OutputStream which encrypts data as it is written to it. A similar abstraction is provided for an InputStream to decrypt data.
Performance is paramount for Conceal, so we’ve open sourced all our benchmarks as well. We look forward to seeing the use cases you develop, and we welcome contributions to improve both the performance and security of Conceal. Read more about Conceal at our GitHub page: http://facebook.github.io/conceal/.
Note: Conceal officially supports Android 2.3 and higher (Gingerbread). It will run on 2.2 (Froyo) phones as well, though full API support for features like benchmarks may be absent.