Where to store password? - android

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.

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 store password on 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.

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.

Android - Storing sensitive data in the sqlite database

I need to store sensitive data in a sqlite database in an android app.
How can I be sure this data is very safe?
I know I can encrypt the data using a key, but where do I store that key? I don't want to ask the user to fill in a key either, I just want it to work on it's own.
Because I am afraid of reverse engineering I don't want to put an encryption key in the code either.
I found out about SQLCipher. It says it's a very secure way of encrypting the data in the database, but why is it that way? Don't I also need to keep a key to unlock that information? Or is this really a perfect way of making sure the data is safe?
And if it isn't, what is an (almost) fail-proof way of storing sensitive data in an sqlite database?
You said...
I don't want to ask the user to fill in a key either, I just want it
to work on it's own. Because I am afraid of reverse engineering I
don't want to put an encryption key in the code either.
Unfortunately, you need to do one of these things (well, probably). You can ask the user for a password and then derive a key from that using an algorithm designed for that purpose (that's known as Password Based Encryption - PBE - and Android includes some good PBE algorithms standard). You could store the key in your code or as a resource within your APK, but then someone would be able to reverse engineer it. You can do so and obfuscate your code, which will slow down the reverse engineering process, but you cannot make it impossible (your code will need to determine the key at some point so it's just a matter of an attacker figuring out how it is doing it).
Other approaches that have been tried here include forcing your client to connect back to a server to retrieve the key over the network...but then what happens if network connectivity is interrupted and what prevents the server from giving the key out to anyone, like an attacker? Well, then you could use mutually-authenticated SSL to ensure only your client is allowed to get it...but then you need to store the client-side SSL private key...which is exactly the same problem you have now. :)
So...the bottom line is that you need a key (or something equivalent) to encrypt/decrypt the data. You can store it and make it harder for someone to reverse engineer it. You can inconvenience the user and make them type in a password. But...you need that secret knowledge somehow.
Symmetric cryptography requires a key to encrypt and the same key to decrypt. There is no way around it.
Do not store the key in the code because it can be decompiled (Like you've said).
Ask the user for a password on the first use and use PBKDF2 to derive a cryptographically secure key to use in the encryption.
Either the user has to enter the password or you need to store it in the memory. What I'd do is, ask the user to specify a duration where the key will be cached in the memory to use for decryption.
And if the duration is expired, the user WILL have to enter the password again.
I didn't check SQLCipher thoroughly but it says it uses AES-256. AES is a symmetric cryptographic algorithm and it needs a key to encrypt and the same key to decrypt.
Is it possible to let apps auto gen a random password? May be gen from place,time or others information this will no need to ask user's pass.

What are some good methods for hashing passwords in an Android app?

I am creating an app that requires the user to register with a remote server, but I want to hash their password before sending it off to be stored in my database.
I tried using the jBCrypt library, but it created a long hang time while hashing. Are there any other alternatives? What would be the best (and safest) way to hash the passwords without creating a noticeable hang?
Your approach seems to be wrong. Unless you have some special requirements, the usual way to do this is the following (not Android-specific, for any web application):
When the users register, take their password, hash it (using a random salt is also recommended), and save it in the DB. That is done so you don't save the actual password in your DB.
When the user needs to login, you send the actual password to your webapp (use SSL to avoid sending it in the clear), not the hash. On the server, you apply the same hashing algorithm as in step 1, and compare the result to what is in your DB. If they are the same, the user has provided the correct password.
In short, you should do your hashing on the server, not on the Android device.
Avoid saving 3rd party passwords at all cost. Saving them is considered a form of phishing. Try to save an authentication token instead of a raw password that you can get using a method like OAuth.
If you do need to send a password to a database on a webserver, just use HTTPS. This will ensure safe encryption over the wire. Then you can encrypt the password as necessary in the database. This method also ensures that your encryption mechanism is not on the device itself which can be more easily compromised.

Categories

Resources