I use the AndroidKeyStore in my app and I'm struggling with some questions. I am quite new to cryptography and I am not sure if I understood the concept of working with keystore correctly.
So I have an app, which encrypts data locally with a key stored in KeyStore. Now I wonder if its possible somehow to protect a key with a password and if its a good practice. I've tried to do it that way
val protParam: KeyStore.ProtectionParameter =
KeyStore.PasswordProtection("password".toCharArray())
keyStore.setEntry(keyAlias, KeyStore.SecretKeyEntry(key),protParam)
But that results with an exception:
Unsupported protection parameter class: java.security.KeyStore$PasswordProtection. Supported: android.security.keystore.KeyProtection
What would be the best way to protect the encrypted access with a password?
Related
I need some string values in my app that I don't want to hard code (one of those in the public key for network communication). So I made a encrypted version using AES algorithm. Now whenever I need the original stringm I need to use my key for decryption, so where should I store this key? It doesn't seem logical to store it as an hard coded string, and I don't want to store my key on the server. What should I do?
You can use JCA. Use its Password-Based Encryption.
This way you do not have to store your key any where.
Whenever you need to decrypt the data, type your password and you are good to go.
http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#PBEEx
Note: The same salt and iteration count that are used for encryption must be used for decryption.
A good way to encrypt and decrypt stuff in your app without hardcoding pwds in the code is using PIN protection screen on the app. Doing this you can derive a final key to encrypt sensitive data and with the same key decrypt everything. Hope this idea will help you to figure out what do you have to do.
I am looking to understand Android keystore for the purpose of storing passwords on device. (https://developer.android.com/training/articles/keystore.html)
In this article it says "Use the Android Keystore provider to let an individual app store its own credentials that only the app itself can access." This is exactly what I want.
So I think the way this will work is like:
1) I will generate a RSA key
2) Store the PrivateKey in the KeyStore
3) Store the PublicKey in some SharePrefs
4) Encrypt Password using the PublicKey
5) Encrypt Password using the PrivateKey.
However I think I am misunderstanding something because this article does not show
1) How to save PrivateKey to KeyStore (I don't see any API showing how keystore added the key)
2) Does not show how to decrypt data with PrivateKey
Infant why is this article talking about "Use a PrivateKey in the KeyStore to create a signature over some data." What does it mean to create a Signature over some data ??? (I want to decrypt data with PrivateKey). And why does it want to verify "signature previously made by a PrivateKey".
So I am lost at this point ... this article started me of in the right place but then by the end I am confused what it is trying to achieve.
Can someone suggest if what I am trying to do makes any sense at all ?
Or should I just save public and private key in my own db ? (not much security there but its the best I can do with given requirement of storing password on device).
Many thanks
Rgds !!!!
I am quoting this line from Using internal storage section of http://developer.android.com/training/articles/security-tips.html
By default, files that you create on internal storage are accessible only to your app. This protection is implemented by Android and is sufficient for most applications.
Now about encryption:
Keystore API is dealing with encryption of the data. And keys are used for secure communication and not for storing password. Passwords are usually irreversible hashes or maps. And do not require decryption but needs only matching.
For example: To communication if you send data encrypted other party involved in communication needs to know what the data is so required decryption key. So if you have sent "Hello I am Crypted" receiver must know you sent "Hello I am Crypted" as message.
For password if you enter some passphrase or passkey it needs to be matched with the stored counterpart. Like if "pass123" is your password stored as "rdi#$$+!#/b" then when you enter a password when process by checking algorithm it should match the stored value and you are authenticated it is not required to generate "pass123".
So, for your application you can use some mechanism(that generates almost unique and irreversible hash) to generate unique key/hash when password is entered and then store it in your app data.
I'm currenlty investigating using the secured/improved Keystore introduced in Android 4.3.
I would like to store an encryption key inside this keystore, this key is used to encrypt a sqllite db and the values contained in my shared preferences.
When I take a look at the KeyStore Sample in the SDK I see the following:
public static final String ALIAS = "my_key"
If someone would be able to decompile my code they would be able to see the cleartext alias (= the key to retrieve the encryption key from the keystore) and hence they would be able to get a reference to my encryption key. How can I securly manage my ALIAS? or am I missing the point here?
The below answer is for 4.3+. There were big changes to KeyStore & KeyChain classes on this release. See here for more info
Keystore access is restricted by UID - your app is allocated a UID on install.
This is what prevents other apps / processes accessing your key pair / private key. The keystore deamon will enforce this.
This can optinally require a device pin for additional encryption. See http://developer.android.com/reference/android/security/KeyPairGeneratorSpec.Builder.html#setEncryptionRequired()
The whole point of using the software / hardware keystore is to get around the situation you describe - which is any hardcoded data in your app can be read on decompilation so it would not be secure.
#Duncans answer makes it seem that you need to keep a password around. I would advise you generate a key pair using the keystore and then use this to encrypt an AES key you can use to encrypt anything you want (much faster than using an RSA key)
You can use your hardware / sortware keystore backed private key like keyStore.getEntry(alias, null); and not pass any kind of password.
See SecretKeyWrapper.java for a good example of this
The alias is not sensitive information. Each keystore is associated with a password and each key has its own (optional) password too. Those are the values that must be kept safe.
Without the password(s), an attacker cannot read your key material despite knowing the alias.
I want to create a simple app which will store some secret information. I will ask the user to create a password for the purpose. Will that be enough to secure information or should I make some other provisions also like encrypting data. Kindly provide suitable guidance.
Yes, if you are storing passwords, you should encrypt them. Check this link to get the list of all possible encryption/decryption options.
As you are telling that the data is secure , you should always encrypt inspite of password protection.
yes Mohit, while storing such secret information on mobile you need to encrypt these type of information for better security.
Have a look at this link
Don't encrypt the passwords. Instead, use Salted Hashing(SHA-2) with random salts(At least 16 bytes) for each user. Then, run the hash through another hashing algorithm, and use that hash to encrypt your data.
Your best bet is to encrypt the data using a secure encryption algorithm like AES and generate the key in a secure way from the user's password thus making each users data encrypted uniquely. The passwords should be stored using a salted hash (like bcrypt or PBKDF2) so that they are not susceptible to rainbow table attacks (where hashes are precomputed in a table for matching).
One drawback of this scheme is that you can have data-loss if the user forgot their password as neither their password nor the data will be recoverable. If the data does not need to be secured that tightly then you can generate a secure key and use it to encrypt all data with the same key, but the password should definitely be hashed and salted when stored back in your data-store regardless.
I'm creating an application that encrypts data with a key that is created each time the user logs into the app. However, there are times when data will be received via a BroadcastReceiver that needs encrypting, but the user is not logged in and so the encryption key is not available.
Security is pretty important and so using a key stored in code to encrypt the data until the user next logs in is out of the question as is storing one in the applications DB despite it being within the apps sandbox.
I've been searching through the Android docs and get hints of APIs to address this situation but have not yet come up with a definitive solution.
Anyone know of the usual solution to this problem? I expect it crops up quite a lot in software development.
Let's see...
Setup: Create an RSA keypair. Encrypt the private key. Store the public key unencrypted.
Broadcast received: Generate a random AES-128 key/IV. Encrypt the key with the RSA public key. Encrypt the payoad with the key/iv. Store the encrypted key, iv, and encrypted payload.
Login: Decrypt the private key. Use the private key to decrypt the AES key. Use the AES key to decrypt the payload.
And since this was the first idea that came to mind, I can't vouch for its security properties.
I'm also not sure what security properties you're looking for — what attacks are you attempting to defend against? Why couldn't an attacker just intercept the broadcast directly? Aren't you worried about it lingering around in other processes' memory?
Two ideas:
The BroadcastReceiver get the encrypted data, do the login by stored credentials and get the key to decrypt the data.
You BR just store the encrypted data and inform the user, so the user logs in to get the decrypted data.
I don't know what your app does, so its just a guess what could be possible...