While full-disk and file-based encryption goes a long way to protecting the data stored on an Android device, for some especially sensitive data like passwords etc., this may not be enough.
The problem is that if an attacker is able to compromise the Linux kernel or gain root access via some other means, then since the kernel is able to read the unencrypted contents of any files stored on the device (once the user has entered their password), the attacker can gain access to any sensitive data. Also, even if an attacker is not able to gain root access, if they can nonetheless compromise your app, then they can gain access to your app’s data.
The solution is to directly encrypt the most sensitive data before storing it.
This approach works for data stored on both internal and external storage (or sent over the network for that matter). In the case of internal storage, the data will be doubly encrypted on a device that supports full-disk or file-based encryption. The data itself will be encrypted, and then the file it is stored in (possibly along with unencrypted data) will also be encrypted.
Getting this right though is hard, and we strongly recommend you speak to a security expert before attempting this.
Protecting your keys
There are several issues that need to be addressed, including very technical ones regarding which encryption ciphers to use, and their various modes.
But there is also another issue, one that everyone can understand. Put simply, if you encrypt something then you want to be able to decrypt it again at some later date. To do so you will need a decryption key. The problem is how do you protect the key?
If an attacker can get hold of the decryption key they can read your data, so we have simply transferred the problem of protecting the data, to the problem of protecting the key. You might at this stage ask if we have gained anything?
Well think about protecting all the nice shiny things in your house. You do that by locking the door. And then you put the key in your pocket. The key is with you at all times and you are able to guard it. This is possible because the key is small. You could try carrying your TV with you at all times, but it will probably soon get rather annoying!
The same principle applies to cryptographic keys. They are much smaller (usually) than the data that they are used to protect. We just need to find the electronic equivalent of your pocket. The answer to that is the Android Keystore.
Secure hardware and the Android Keystore
The Android Keystore provides access to special secure hardware for storing cryptographic keys.
The Android Keystore was significantly enhanced in Android 6.0 (API level 23) to provide more capabilities on those devices with the hardware to support them. On devices with the appropriate hardware support, keys can be generated within the secure hardware, and then used to perform cryptographic operations on user data, without the keys ever leaving the secure hardware. It is simply not possible to extract (at least through software means) the keys stored in the secure hardware.
When a key (or key pair) is generated in the secure hardware it is also possible to specify access controls that must be enforced to protect use of the key. This can include the option of requiring the user to input their device password every time the key is used (or provide their fingerprint on devices with a fingerprint reader).
More details about the Android Keystore can be found here.
Notes for Nerds: impressive as this undoubtedly is, it still may not be completely secure. But then nothing ever is. The point is that even though malware can never extract a key from the secure hardware, it may still be able to use it. Use of keys may be subject to access controls like requiring the user to enter their device password, but if an attacker is able to gain root access then they may be able to install a keylogger (software that records everything the user types – including their password!), and that may then allow the attacker to use any keys stored in the secure hardware. If one of those keys has been used to encrypt data also stored on the device, then the attacker may be able to decrypt the data. Whether such an attack is possible may depend upon the specifics of the device.
終わり!