I'm implementing backup in my app, following the instructions in the official Android documentation. The information I'm backing up is potentially sensitive, so I'd like to encipher it, as per the recommendation in the above document:
You should always be cautious about using backup to store sensitive data, such as usernames and passwords.
The recommended approach to ciphering user data, of generating a random key when needed, and storing it, doesn't help in the backups case, because if I'm restoring a backup, the generated key has probably been lost (or would have to be included in the backup). Similarly, I can't use any device identifier (such as the IMEI) to generate a deterministic key, because the backup might legitimately be restored onto a different device.
Asking the user for a passphrase to secure the key would work across devices, but onRestore
is done entirely in the background. To get a passphrase from the user, I'd have to save the ciphertext to storage, make a note for next time my main activity is started, and prompt the user then. Apart from that faff, I don't really believe the user is going to enter a passphrase once, never use it again until the restore happens, potentially years later, and then be able to remember it. I wouldn't! And then there'd be no way to restore the backup, and I might as well not have implemented backup at all.
It seems like the only reasonable option is to have a fixed key that's stored in my APK, but I'm sure I don't have to explain here why that doesn't really provide any extra security. I'd consider it if I were only storing secrets to internal storage, but anyone who can install a dodgy backup transport on the device, or illicitly access the backup server, wouldn't be inconvenienced by having to decompile or inspect the app.
Can anyone offer me a better option?