I want to encrypt my Realm database and store the key in a secure location.
I have been doing some reading and it seems that storing in the Android KeyStore may not be the best idea since it's based on a device's screen lock.
Moreso, some articles say that if the screen lock is changed between pin, password or pattern, all the keys stored in the Android KeyStore are lost and have to be recreated again.
Is there a more secure way to generate the keys and store them in a different location?
What you can do is encrypt your key using whatever algorithm you want (not a deprecated one, obviously) and store it in the internal storage of your app, so it will be private and neither other apps or the user will be allowed to access it.
Related
When you encrypt the app's data stored on the device, it is recommended to use the KeyStore to generate and save the key Material used for the encryption.
If the user wants to backup the app's internal storage, he can use adb backup or Google's Cloud Backup. That's what I have understood.
But when the data is encrypted by keys stored in the Android's KeyStore, is it possible to restore the backup the user/Google made?
Or does the the use of encryption prevent the backup function?
It will not work. This is very sad that Google force two things that don't work together. Keystore on Android doesn't have a backup option like Keychain on iOS.
Your data will be backed up but after restoration, you will not have an option to decrypt it.
You should use a different way to backup data - the easiest one is to have user's account and store his data on your backend.
I wrote about it more here:
https://medium.com/#thecodeside/android-auto-backup-keystore-encryption-broken-heart-love-story-8277c8b10505
Is there any understandable examples of using KeyStore in Android?
I can't really understand how do I have to protect my password/token/anything_else in Android application in ROOTED device from being used by hackers who have physical access to the device.
I understand i can generate KeyPair with some ALIAS, and use it's private key as database password for example, but I'am interested in: can any hacker read this ALIAS from my decompiled apk(because i can't obfuscate alias string) and build another app which uses same ALIAS to get privateKey from android KeyStore?
Any solutions?
I can't really understand how do I have to protect my password/token/anything_else in Android application in ROOTED device from being used by hackers who have physical access to the device.
You can't. Client Authenticity is Not the Server's Problem.
Let's say you store an encrypted value in your app rather than storing the value directly. Where's the key to decrypt this value? The app will necessarily need to decrypt this value. Now all a hacker needs to do is download your .apk, plug it into Lobotomy, and they will quickly figure out what's going on.
You're better off simply never placing sensitive information on the device itself, if you want to hide it from the people who run your software.
Do you need to store the key in the app?
What if at first install you ask the user to set a password, you encrypt your SQLCipher DB with that key (maybe hash it too) , then every time, when the user starts the app, you ask the password.
I'm writing simple offline dictionary application. All data is stored on SQLite database.
If we assume that database is encrypted, app must use some kind of key, in order to have access to it. Also, we assume that this application is completely offline and does not access to any remote servers.
That means that key will be stored in apllication itself. I was trying to find out a lot of methods of hiding this key in app and all of them are flawed.
Is it even possible to hide this key implicitly in app itself?
If the app automatically displays data, it is not possible to protect that data.
Your app must store the key somewhere. Regardless of how much you try to obfuscate your code, it is still possible to decompile it (or just execute the obfuscated part, until the key comes out).
Or looking at it in a different way: hiding the key is a form of encryption. So now you need a second key to encrypt/decrypt the first key. (But with obfuscation, the 'key' is the program structure, which is less secure than a real cryptographic algorithm.)
The only way to protect the data would be to avoid storing the key by requiring the user to enter the key (as a password, or some separate token) whenever the app is to be used.
This implies that the user is trusted not to give the key away.
I have an interesting situation here. My app stores sensitive info input by the user such as a social service account of theirs. I use a master password input by the user to generate a SecretKey, and then use AES encryption and store its SHA1 hash and the encrypted data on device, but not the master password itself or the key.
The issue is that in case the user forgets their password, there is a secret question they can answer and change the master password. So when the master pass is changed, since the previous password (and the associated SecretKey) are forever gone, I can't decrypt the stored strings and show the decrypted data to the user.
Here are the solutions I can think of:
1 - Store the password, which I have heard is totally unsafe.
2 - Store the SecretKey, but I have heard this is unsafe too.
3 - Store user data in database unencrypted, which is unsafe I guess.
4 - Wipe the entire database everytime the user forgets their password, which is silly I think.
I need a way to overcome this and I simply can't think of a secure way to pull it off.
It is crucial that this be solved for my app to fly. Any and all help is really appreciated.
Well it's a bit unfair to remove all of user's data just because they forgot a password.
Then they shouldn't be storing stuff in a container that requires a passphrase. Next, you'll argue that anyone should be able to open any wall safe using a hockey ticket stub and some chewing gum, because somebody might forget the combination for the lock.
Please note that your line of inquiry assumes that the approach described in your opening paragraph is the correct way to build the app that has the security characteristics that you desire.
For example, the right answer to meet your requirements is to not encrypt the data at all, but instead force the user to have their device full-disk encrypted. You can use DevicePolicyManager to see if the device has full-disk encryption enabled, and you can refuse to run if they do not. Then, the data is encrypted, as is the rest of their device, but you are no longer having to deal with passphrases and recovery scenarios — that's up to Google and device manufacturers.
Isn't there any other way to decrypt the data?
Only if you have a vulnerability in your app (a.k.a., a backdoor). This is the ticket-stub-and-chewing-gum scenario. The point behind encrypting data is to make it so that it cannot be encrypted without the passphrase or equivalent security key.
So, another approach to your app is to dump all your key stuff and use KeyStore. Particularly on devices with a hardware-backed KeyStore, there's no way to really get at the key, short of unlocking the device. Here, you don't have to worry about the full-disk encryption (as you're encrypting the data) and you also don't have to worry about the user forgetting the key (because the user never has the key). It also saves you having to have the user enter a passphrase. But now you can't readily back up the data (as it's useless without the key), and if the user's device is run over by a bakery truck or otherwise destroyed, the data is gone. You could provide options for the user to back up their key (e.g., to removable media), but now you are reliant upon them remembering where they stored the backup, storing the backup key securely, etc.
Or make the same SecretKey as before?
Since nobody but you knows how you are creating this, nobody but you can answer your question.
I would also suggest that you read this paper, as it outlines how 88% of Android apps that they surveyed, who tried to cobble together their own crypto approach, screwed it up.
I have to store the private key of my app in a secure location in the android device, i read about certStore, but it doesnt allow to store a file in it.
Is there any location where I can store it securely and doesn't get deleted if app re-installs.
You can store the key in the Preferences of your App. This will protect the key from
getting read by other applications because of the underlying file system restrictions of
the Android system.
But this won't protect the key from being read by the user itself.
and if you want to use this shared preference after your application removed and again installed in device then try for Android Backup Manager.
I think its help you in re-installation of your activity's data.
EDIT: Android (unfortunately) does not provide a way to do so. The approach I've used
before is to encrypt this token with another key generated within the app.
Your app key can be algorithmically generated. This, however, is only as secure as
your algorithm. Once that is known this is equivalent to storing the token in plain text.
Thanks.