I've read about Keystore which is in fact a repository of security certificates – either authorization certificates or public key certificates – used for instance in SSL encryption.(by Wikipedia).
Android developers use the Keystore to store their encryption keys in it, instead of
embedding the encryption key inside the android application. That's supposed to solve the problem of a hacker which is decompile their app and get the encryption key the is used by the app.
Whenever you want access the data inside the Keystore you have to specify a password. What prevents the hacker from decompiling the app, extracting the Keystore's password, and then gathering the encryption key inside the Keystore?
Or maybe I got it all wrong?
They are likely storing that key encrypted in the keystore itself. To access the key store, you will need some combination of the user's passcode for unlocking the android device and/or a device specific code such that only that device can decrypt the keystore.
Related
I want to use one secure key to encrypt and decrypt data on device without saving it in SharedPreferences or DataStore. I want to generate that key using in app authorization (passcode and biometrics).
I know generating secure key with biometrics is possible using AndroidKeyStore. I know I can generate another key by using passcode. Is there any cryptographic way to use one of those keys to encrypt/decrypt local data?
I have tried generating keys with biometrics and passcode. But I could not find a way to encrypt and decrypt data with either of those keys. For example: user logs in and sets passcode and fingerprint. App should encrypt data so it could be decrypted using one of those authentication methods.
I am wondering how do other secure Android apps solve this problem. Can someone provide me an example where could I look into that?
I need to keep and use a 3DES key in an Android application in order to communicate with a legacy sytem. I would like to use the Android Keystore provider for its high security features, but it seems it doesn't support 3DES.
My understanding is that in an Android application, you can either use the default Keystore provider and manage your own protection passwords, or you can use the Android Keystore provider, which is far more secure and manages the protection passwords for you. I understand that if you don't provide a KeyStore.PasswordProtection when creating/loading a keystore with the default Keystore provider, the entire keystore is stored as plaintext and the keys are vulnerable to being directly extracted by an attacker.
What are the best choices for safely storing and using a 3DES key in Android?
My idea is to generate an AES key using the Android Keystore provider and generate a random password to protect my 3DES key. Then, I can create a default provider keystore, protect it with the generated password and store the 3DES key inside. Then, I use the AES key to encrypt the password and store the encrypted password in SharedPreferences. Now, I can fetch the encrypted password from SharedPreferences, decrypt it via the Android Keystore provider, use it to unlock the default Keystore Provider and then just use the 3DES key for encryption/decryption.
Does this approach have any critical vulnerability? Could you suggest another?
I would like to use the Hardware Android Keystore, to safely encrypt sensitiv data and store it locally on the device. The standard implementation seems very easy and there are enough tutorials out there on how to implement it.
But the requirements I got require that a user provided secret (a user pin or password that the user has to enter) is included into the encryption of the senstive data. So that encryption/decryption of the data only works with the known user secret and not without it.
I haven't found a way to provide a user secret into the Android Keystore process.
How can I encrypt/decrypt data with the Android Keystore that needs a secret user input to actually work?
AndroidKeyStore does not provide any API to set user provided password for the generated secret. Only thing that you can do is, setting a KeyGenParameterSpec.Builder#setUserAuthenticationRequired flag to true for system provided user authentication (pin / pattern / fingerprint etc.. )
The real power of AndroidKeyStore is comes from the TEE and Secure Hardware. So that, any other option rather than using the key directly in the AndroidKeyStore should be considered as less-secure. So that, generating PBKDF2 using both user provided secret and key store encrypted secret doesn't makes your encryption more secure. Because, that new key should be managed in an application memory and is vulnerable (of course in compromised device) until you complete encryption and wipe all of the key bytes.
But in secure hardware, AndroidKeyStore doesn't even loads your keys in a memory. Every operation happens in a separated secure hardware.
If your requirement is not strictly "having one key" and "encrypt data only once", you may consider to encrypt your data twice using both of the secret from AndroidKeyStore and user key which is derived from user password.
And also, you may want to read this paper: http://www.cs.ru.nl/~joeri/papers/spsm14.pdf. In this paper, authors also mention Bouncy Castle keystore with user-provided password.
I have done an Android Application using an ECC Key pair. When I have developed it last year, I wanted to create the ECC key in the Android Keystore. Unfortunately, this ECC key is used to generate a session key thanks to ECDH, and ECDH is not supported by Android Keystore (this is what I have been said here: ECDH with key in Android Key Store )
I have followed the recommendations: I have created an AES key in the Android KeyStore and I have used it to encrypt the ECC key before storing it in the SharedPreferences. Android KeyStore ensures that the AES key cannot be extracted and that only my application can use it to decrypt the ECC key.
I now have a concern for which I would like your advices:
What if someone install my application on a rooted phone, gets the APK, uncompile and modify it to print the ECC key after that has been read and decrypted? I don’t have this skill but I guess that some hackers do.
If that’s feasible, it means that the protection that I have used is not efficient.
Using ECDH is non-negotiable in my case so what solution do I have to secure my ECC key pair?
Thanks
There is no way to ensure that the key is non-extractable unless it's backed by secure hardware.
And for the rooted phone case, attacker doesn't need to modify and reinstall your APK in order to use your key. Any app on that device with the root permission can hook into your app and behaves like it. Even in trusted environment they can use your hardware backed key. Only thing they can't do is, extracting the key from the device.
You may want to read the relatively old paper about TEE and AndroidKeyStore: http://www.cs.ru.nl/~joeri/papers/spsm14.pdf . Especially "Overview of the results for Device-binding"
In order to reduce attack surface, you can:
Protect your key with the user-provided password along with the AndroidKeyStore AES key
Use SafetyNet API to check device integrity: https://developer.android.com/training/safetynet/attestation
I am developing an android messaging app. When user signup rsa private and public key are generated and with these keys and aes messages are encrypted and decrypted.
Private key is stored in the phone and public key in the server. If the user resets or uninstall the app all keys are lost so there is no way to decrypt the old messages.
How can I retrieve old private keys without storing it in server when user uninstalls app?
Are you using Android Keystore to store the keys or using your own file storage?
Android keystore
With Android Keystore there is no way to recover keys because they can only be used by the application that created them and are discarded if there are substantial changes.
I guess you are using the RSA keys to negotiate an AES symmetric encryption key. Therefore you will need to backup the AES encryption key( for example in the server...), and stablish a mechanism to recover the key like the common "remember password" utilities
custom key storage
If you are storing the keys into the device without AndroidKeystore, you could define your own mechanism to restore the keys. For example, encrypt the key with a password and storing the key into a public directory of the device. Then the key can be recovered prompting user for the password
Note: Take into account the security risks in each case. For example a non-encrypted AES keys into server implies that a malicious server could decrypt messages. Or a weak recovery key mechanism will descrease the whole security level of the system
There are various ways to persist data in Android. Databases, SavedInstanceState, SharePreferences and files. Only files persist after you application is unInstalled by the user. Saving it in a file is about the only option you have.