Implement Secure Data Storage
Details
Storing data securely on a mobile device requires proper technique. Whenever possible, simply do not store/cache data. This is the most sure way to avoid data compromise on the device.
Remediation
Do not store sensitive data where possible. Options to reduce the storage of user information include:
- Transmit and display but do not persist to memory. This requires special attention as well, to ensure that an analog leak does not present itself where screenshots of the data are written to disk.
- Store only in RAM and clear at application close (see also best practice 2.5 Securely Store Sensitive Data in RAM)
Additional Layered Encryption
If storing sensitive data on the device is an application requirement, you should add an additional layer of verified, third-party encryption (e.g., SQLCipher) to the data as device encryption is not sufficient.
By adding another layer of encryption, you have more control over the implementation and attacks focused on the main OS encryption classes. For example, attacks on iOS data-protection classes (which are now compromised) will not succeed in compromising your application directly. This approach has the drawback of being more complex and, if implemented poorly, can actually reduce security posture. If you are not confident in including a verified third-party crypto library Apple and Android’s common cryptographic libraries provide a number of standard cryptographic functions which, if used properly, can provide a reasonably secure cryptography implementation.
Some options include:
- Encrypting sensitive values in an SQLite database using SQLCipher, which encrypts the entire database using a PRAGMA key
- The PRAGMA key can be generated at runtime when the user initially installs the app or launches it for the first time
- Generate a unique PRAGMA key for each user and device
- The source for key generation should have sufficient entropy (i.e., avoid generating key material from easily predictable data such as username)
Whenever you encrypt user data, aim to encrypt it using a randomly generated master key, which is also encrypted using a passphrase supplied by the user whenever data is accessed. This will prevent data from being easily recovered should an attacker extract the master key from the device. Due to the number of vulnerabilities in Apple’s data-protection APIs and keychain and the lack of device encryption on the majority of Android handsets, it is not recommended that the master key or a passphrase be stored on the device at all.
Android
In Android remember that the external storage such as SD Card has no fine grained permissions and that any app by default has read access to the storage and can read all files. Since Android 4.4 apps can store data on the SD Card in a protected way under certain circumstances (see http://source.android.com/devices/tech/storage/).
Android and iOS implement standard crypto libraries such as AES that can be used to secure data. Remember that data encrypted with this method is only as secure as the password used to derive the key and key management. Consider the password policy, length and complexity versus user convenience, and how the encryption key is stored in memory. With root access it is possible to dump the memory of a running process and search it for encryption keys.
Also note that using the standard cryptographic provider “AES” will often default to the less secure AES-ECB. Best practice is to specify AES-CBC or AES-GCM with a 256-bit key and a random IV generated by SecureRandom. You should also derive the key from a passphrase using the well tested PBKDF2 (Password-Based Key Derivation Function).
iOS
The Data Protection APIs built into iOS, combined with a complex passphrase, can provide an additional layer of data protection, but are not as secure as implementing additional, third-party verified cryptography. To leverage this, files must be specifically marked for protection (see best practice 6.1 Use the Keychain Carefully). Any data not specifically encrypted using Apple’s data protection APIs is stored unencrypted.
References
- Android/iOS Full Database Encryption - http://sqlcipher.net/
- Android Storage Options - http://developer.android.com/guide/topics/data/data-storage.html