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
Related
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 an android app which is receiving data from a php page using HTTP get/post request. I'm encrypting the data at server side and decrypting in android. I'm using AES 128bit Encryption, I have hardcoded the strings key and iv in the android side. If anyone reverse engineers my apk, they can get the key and iv easily. Is there any way I can store these 2 strings securely in the apk.
Please help
You can use Android Keystore Keystore provider feature that was introduced in Android 4.3 (API level 18).
The Android Keystore system lets you store private 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 private key material remaining non-exportable.
https://developer.android.com/training/articles/keystore.html#UsingAndroidKeyStore
No, that would be akin to solving the DRM problem.
You can of course hide the key in plain sight, for instance using the answer of Alireza but it's impossible to secure the key without controlling the devices it is stored in.
You can of course implement your own transport mode security: that way you do not have to have a secret key in your APK (just a trusted public key or certificate).
However, the quick, easy and above all secure way is to use TLS. Especially when using forward secrecy (EDH_ or ECDHE_ ciphersuites) your data should be secure.
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.
My android application has account, passwd and other important information needs to store in its database. So concern about security, i am now studying encrypt these data to save in the database and decrypt it again when needed.
Using salt and iteration can make the encrypt data more strong. This part i understand how to do it. But my concern here comes that there is a lot discussion that not suggest to hard-coded AES key or PBE key. But without the key, i can't decrypt the data again (I do need to decrypt it again).
Is there any good suggestion for android application to save the key?
Thanks a lot.
It is suggested that the encryption key should be managed using Android Keystore, it is the safest option available at the device end to manage the encryption key. Android Keystore went through lots of changes from the day it was available for the user applications and that is why I have categorised the recommended approach based on the API level:
API Level < 18: Android does not support Keystore for API level 17
and below. For API level 17 and below, it is recommended that the
application use PBKDF2 (Password-Based Key Derivation Functions)
securely such that the application should generate the encryption key on runtime while login(using user's password). The encryption key should not be stored in the device and should be dynamically generated whenever required using the user's password since there is no secure place in the device to manage the key.
API Level >=18 <23: Android supports Keystore for API level 18 and above. However, for API level 22 and below the support for AES
encryption is not available. It is recommended that the application
generates a random AES key using the default cryptographic provider
and encrypt the AES key using RSA public key, generated using Android
Keystore through keyPairGenerator. Once the encryption key is encrypted, the same can be stored in the private data storage of the application (For ex: SharedPreferences). When the application starts,
the AES key can be decrypted using the RSA private key.
API Level >=23: Android supports Keystore with AES support for API
level 23 and above. We can directly generate the random AES key using
generateKey API and the same is managed automatically by Android
Keystore.
Save your data in .so file. you need to implement ndk integration in your project. It will make it much more difficult to hack. and you can get your value back from c++ file. Also check for package name in c++ to make sure your so file is not used in any other application.
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.