How to store password on Android - android

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.

Related

Generating a unique encryption key or salt per app installation

I'm working on the topic on how to securely store sensitive data on an Android device. Of course there's no 100% secure method, I'd like to get as secure as possible.
I've read through the official recommendations.
Just as an example, I have an app that stores text (e.g. private diary). The text is stored in an xml file, which is encrypted (aes256) with a key, that is stored in the Android KeyStore.
This should mean that the data is stored securely in the encrypted xml file. A root user can still access the key from the KeyStore and decrypt it, or fetch the data once its decrypted by the app.
However, this also means that every app uses the same key. So I can install the app on my phone and use my key to decrypt xml diary files from other phones.
The question is, how do I create a key or at least the salt, that is unique per app installation?
The Key Derivation Function KFSs are just for this
From the Wikipedia;
In cryptography, a key derivation function (KDF) derives one or more secret keys from a secret value such as a master key, a password, or a passphrase using a pseudorandom function.
You can use Argon2 was the winner of Password Hashing Competition.
Choose the IMEI number as one of the parameters, the user's password and a random number from the phone.

how to prevent database and shared preferences from being hacked

I am developing a password manager application that stores your accounts and their passwords in a database and stores a password of the application in a shared preferences so that your accounts can not be reached by others
what is the best way to protect the data
suppose that I create a method to encrypt the data and create a method to decrypt it so that a normal user can read the data
if a device is rooted can the hacker move the application data to another device with the same application so that he can read the database even if is encrypted because the application in the another device has the decryption method
is there a back-door method so that the hacker remotely transfers the data to anther device and decrypts the data by the application itself
If the encryption method contains generating random encryption key and storing it within the password string as a next line (multi-Lines are not allowed in passwords) is this a safe way because the hacker hacks the totally password string which encludes the encryption key then decrypts it with the application
suppose that I create a separate encryption key....It should be stored somewhere permanently....But if the hacker can access it can he crack the encryption by the application itself? if yes can the encryption key stored somewhere where the user can not reach it
note: making the encryption key related to the IMEI of the device is not a solution because I intend to make the application sync data between devices so many devices may have access to the same account
If someone has root, they own everything. From a fundamental perspective, they could pretend to be the user, your application would decrypt the content for them, and then they'd have the results.
Having the sensitive content be encrypted using a master password as a base means that it would be safe to some types of attacks -- but if the attacker can have a piece of software watch for that password entry they can still steal it. It does protect against some parts though, since when the software is "cold" (i.e. the password isn't there or loaded) the protected data is safe (if the encryption is solid).
There's a external library which is very good to encrypt the Shared Pref dat that uses Facebook Conceal
Hawk

Android Keystore, secure value of key

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.

Do I really need to encrypt data?

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.

Where to store password?

I am writing an android password manager application and i want to store the master password somewhere but i don't know where. Should i encrypt the master password that the user gives me with a hard coded password that i choose and then store it to the database? or should i do something else?
You should never store unencrypted passwords.
For passwords, that you can't encrypt safely (because you have to store the decryption key somewhere), you should only store a unreversible hash of it.
That way you can compare the password to the hash when the user gives you the password. If it matches, you can decrypt the stored user:password pairs with the given password.
PS: Don't forget to salt the hash and please do it properly.
No, no, a thousand times no.
If you are allowed to look at GPLv2 code, take a look at the KeePass source code.
The master password is turned into a key (password based key derivation), and that key is used to encrypt and decrypt the individual pieces of data (individual passwords).
Therefore, the process is similar to this:
1. Turn off any kind of swap-to-disk you can turn off. Ask the user for the master password.
Turn the master password into an in-memory-only master encryption key, by using something like PBKDF2(HMAC-SHA-256, master password, stored random salt*, 2000000, 256) - PBKDF2 is also known as RFC2898 and PKCS #5. HMAC-SHA-256 is the hashing function. Master password is whatever the user entered - this is never saved in any form at all! Stored random salt is a 64-bit or larger cryptographically random value generated fresh whenever a new master password is selected, and saved instead of saving any form of the master password whatsoever. 2000000 is the number of times we're going to run the HMAC, which is stored and should be user selectable - this should be as many as you can stand to wait (KeePass has a function to benchmark them and see how many take 1 second - I recommend increasing that to 4 or 5 seconds). 256 is the number of bits of output required - in this case, I'm assuming you're going to use either CAMELLIA-256 or AES-256 to encrypt your passwords (just match how many bits your encryption function uses for the key).
Yes, scrypt or bcrypt can be used instead.
Check to see if the master password was correct: If we're going into an existing database with an existing master password, use that in-memory-only key to decrypt some fixed data, like a 'default' password. If value decrypts to the value you expect, the master password entered was correct, if not, the master password was wrong and/or the database is corrupt. If we're starting a new database or changing the master password, encrypt that 'default' password and store the encrypted value.
Use the master encryption key to decrypt URL's, usernames, notes, and other non-password data.
Use the master encryption key to decrypt existing passwords only per the user's request (but only the precise password the user requested) and then overwrite the data with random garbage as soon as they're done with it or a timer runs out. Encrypt new passwords using said master encryption key.
As soon as the user's done or a timer runs out, overwrite all variables (most especially the in-memory-only master encryption key) with random garbage.
Note you're storing:
Number of iterations
Salt
Encrypted "fixed" password used solely to validate whether the master password is correct
Encrypted username, URL, notes, etc.
Encrypted individual site passwords
You are never, ever storing either the master password or a hash of it. You never ever compare the master password, a hash of it, or even the generated master encryption key to anything else. You only ever take a master password and turn it into a master encryption key, and then use that key to encrypt or decrypt data - known data (the "fixed" password) lets you see if that key gave the expected results. Unknown data (everything the user entered and cares about) is also encrypted or decrypted when you know the master password is correct.

Categories

Resources