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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With