Android Auto Backup + Keystore Encryption = Broken Heart Love Story
You care about your user’s data and you encrypt them. Android provides you Android Keystore to make it easier — great! You also want to help your user migrate the data when he changes the phone or wipes out data. Here also you can use built-in Android Auto Backup for you — amazing!
Both things come directly from the framework and Google encourages us to use them by default. Could be something better? Anything could go wrong? Unfortunately everything.
TL;DR
You have to remember that Android Auto Backup will fail if you use Android Keystore to encrypt the data. Think about the different backup mechanism.
Maybe store data on the backend? Read further for more options!
The problem explanation
Auto Backup for Apps automatically backs up a user’s data from apps that target and run on Android 6.0 (API level 23) or later.
By default includes files in most of the directories that are assigned to your app by the system:
- Shared preferences files
- Files saved to your app’s internal storage
- Database files
- Files on external storage
It is turned on by default for all apps from Android 6.0.
The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.
You can (and you should) use this keystore to encrypt your data.
It is used by Jetpack Security Library to encrypt SharedPreferences and Files.
What is the problem?
I highlighted two things that are at the heart of this common problem: non-exportable keys in Keystore and turned on by default backup. When encrypted data of your app will be backed up you will never be able to decrypt it. Broken Heart Love Story Ended.
I’ve seen too many times when developers were confused about why backup doesn’t work with encrypted. Sometimes they even didn’t notice it. Sometimes they just turn off the auto backup, but Product Owners want this function — this works on iOS! Yeah, but they have this “ecosystem” that shares their Keychain.
What can we do?
1. Don’t encrypt
But, you don’t want to do this because you care about the user’s data privacy and your own security.
2. Don’t auto backup — backup on backend
Yes, this is a kind of good approach. In most cases the best approach.
On the other hand, sometimes you don’t want to store your user’s data.
3. Use user input to encrypt
Use user input to encrypt the data, for the example user password. Just don’t use the PIN — it’s too short, and maybe don’t use the plaintext password — hash it, add something, etc. You can store this password encrypted using Android Keystore encryption.
This is the best approach from a security perspective.
4. Use exported token
You can use an exportable token to encrypt data, and then your user can restore data by entering this token or scanning QR code. Users don’t need to have an account.
Now user’s security depends on how he stores this token. However, this approach needs some extra UX (can we say that — extra UX? 🙂
5. Use exported backup
Similar to above but instead of exporting a token you export the whole database. Simpler in implementation.
6. Use the static key
Hide static encryption key deep inside the code. Split it into few parts, use Native C++ code, etc. You can change this static key periodically, and provide encryption migration.
This is almost the worst approach from a security perspective. Better only from no encryption one. But sometimes it’s enough and this is the simplest for users and developers.
How to backup?
Which option should you choose? Storing user’s data on the backend is the best approach in most cases. When you don’t want to store user data you can choose between good security (option 4) and good UX (option 5). Sometimes you can mix approaches and store on the backend data for registered users and choose something else for the rest of them. You can also don’t backup data of non registered users and use this as an argument to convert them into registered ones!
In the end, I just want to say that this is sad that these two important, and default features from Google don’t like themselves.
Originally published at https://www.thecodeside.com.