0

I'm writing a WPF password manager application to practice programming, so far this is the scheme I intend to use to store master password and individual site password:

Master password:

  • Generate a random salt.
  • Hash the master password + salt with SHA256
  • Stored the hash and salt in DB as text.

For each individual site password:

  • Generate a random salt.
  • Hash master password + salt with SHA256
  • Use the hash as AES256 encryption key to encrypt site password.
  • Store the encrypted site password as binary blob and the salt as text in database.

Obviously for this to work the user will have to retype master password everytime he want to decrypt a site password, or I will have to store master password in memory.

Now to my question:

  • Should I use the same hash function while hashing the master password and creating encryption key, or should 2 different hash functions be used?
  • Does the way I handle individual site password make sense?
gzup
  • 35
  • 5

2 Answers2

1

If you want to create an encryption key or store a hashed password, you want to use a key derivation function, not a simple hashing function like SHA-256. A KDF is like a hash that gets applied many times, but is typically designed to be computationally expensive in order to make brute-force searches harder. While you might be able to use SHA-256 as a KDF by calling it multiple times, this is not the standard way to do things, and may be much less secure than it appears since you need a very large number of iterations to provide effective mitigation against brute-force attacks.

The most popular (read: carefully studied and probably secure) KDFs in current use are PBKDF2 ("password-based key derivation function 2") and bcrypt. Either is suitable for hashing and storing passwords, as well as for creating encryption keys. There are also some newer algorithms such as scrypt which may be more secure under some definitions, but it is my understanding that they are newer and less well-studied. "Security" is, of course, not a numerically quantifiable variable, so it's not entirely meaningful to say that "algorithm X is the most secure choice."

Generally, a KDF will take a parameter called the work factor or the number of rounds. This describes how much computational effort is required to compute a hash or derive a key. As computers get faster, this parameter needs to be increased in order to ensure that your hashed passwords remain sufficiently resistant to brute-force attacks.

Kevin
  • 916
  • 6
  • 12
0

Disclaimer: I am by no means an expert, I have just been researching this topic for the same reason. Also I realize this is from a while back.

One problem that may arise from this is that it may actually make brute forcing your encryption key easier. Since hashing algorithms are not 1:1, there may be multiple valid "Master Passwords" that produce the same hash you use to encrypt the site-specific passwords.

As gzup mentioned, I would take a look at how current Password Managers do it and try to rely on your own cryptography as little as possible. Also, check out BCrypt for a slower hashing algorithm to hash your master password (This makes bruteforcing a little more tedious).

  • 1
    Good suggestion to use bcrypt to make attackers work harder against the database, but in practical terms hash collisions are a non-issue for any cryptographically secure hash recommended for common use. Intentionally or even accidentally finding a hash collision for SHA256 would be a really really noteworthy event. It hasn't happened yet. Another suggestion would be to do like KeePass and make the number of iterations of the hash configurable. – Ben Jan 05 '16 at 16:12
  • @Daniel, why would the second key's hash continue to match the first key when hashed with different salts? – NameSpace Feb 04 '16 at 07:30