I would like to provide the security to symmetric key which I have used for encryption and decryption.
I would like to Encrypt the symmetric key and store in shared preferences.
How can I do this?
Actually this is not a very advisable strategy.
You should never store keys in your app, since you can not trust a delivered app.
The only way to do this is to have a trusted server wich has user accounts, that use the apis that need to be secured.
Collection of all reasons
Reasons why google does not advice to do so, and counter measures
Related
I'm working on an Android multi module (multiple apps) project and encountered a use case where I have to save some secret information that could be accessed by all these apps. My idea is to encrypt the secret information using a private key that is saved inside the KeyStore, and save this information in a file that I'm planning to store in the device (not external storage). My question is, would I be able to access this private key inside the KeyStore from another application and then use it to decrypt the secret information that is saved in the device?
I was looking at Android's KeyStore documentation, and if I understood it correctly, I can use the KeyStore APIs to save the cryptographic keys and use them with in the same application. But also the KeyChain documentation says I can use these cryptographic keys across multiple apps with in the system. I'm quite confused about how I can combine these two APIs and make it work for my use case. Any help is appreciated. Thank you.
My idea is to encrypt the secret information using a private key
You encrypt with a public key, never with the private key. The private key is used for decryption.
If you create public keys for all the apps then you can decrypt with individual private keys for these apps. Of course you'd have to trust these apps and the public key pair of each app in advance; I'm not familiar enough with your setup to make any recommendations in that regard.
To be honest the KeyChain API seems more about TLS authentication than anything else and I don't think it fits your use case. The API of the choosePrivateKeyAlias for instance only talks about authentication and a server requesting a key chain.
Key stores can be can in principle be distributed. Or course, to access / decrypt them you'd still need a key distributed within each app. You can share the information for specific signed applications only it seems. Possibly just the security of sharing the data privately without encryption already fulfills your use case? Key management is tricky, after all.
Caveat: I'm not terribly well known with the Android security model; hopefully my general knowledge of cryptography & security steers you in the right direction.
There is android:sharedUserId property. From the doc:
Apps with the same user ID can access each other's data and, if desired, run in the same process.
Unfortunately, it was deprecated in API 29 without proper replacement.
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
Is it possible to save a string in the keystore and then retrieve it?
I have an AES password already generated, I just want to store it in a safer place than the database.
All the examples I have seen store an AES key that is generated at the moment. I can use this solution if I could have access to the original key to send it to the server, is this possible?
You can store the AES key into AndroidKeyStore safely. The keying material can be used by your application without exposing it.
But a key in AndroidKeyStore is not extractable, so in order to be able to send the AES key to server you will need to generate the key outside, and wrap it using an additional encryption key managed by AndroidKeyStore. Then the encrypted AES key can be stored in the device or even in the server
Please see my answer here with all options explained: how to securely store encryption keys in android?
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.