0

Ive done a bit of reading on the subject of Hashes and Salts and I came up with an idea for a salting scheme but I wanted to check it with some people more learned than myself.

My basic idea is to use the initial password hash as a salt for a second hash ie.

password = 'foobar'
final_hash = sha1( sha1( password ) + password )

If anyone can explain why this might be a bad idea Id really appreciate it.

Thanks!

5

You will not achieve anything. Consider two users with the same password, salt, among others, is designed to achieve different hashes for the very same password.

In example:

  1. User A pass: foo, salt: abcd = hash ( abcd + foo ) = 23424098FAD
  2. User B pass: foo, salt dkes = hash ( dkes + foo ) = 8734536EA43

But with your algorithm you will end up with the very same hash:

  1. User A pass: foo = hash ( hash(foo) + foo ) = 123AB2344
  2. User B pass: foo = hash ( hash(foo) + foo ) = 123AB2344

Also, don't roll your own.

  • But the salt still needs to be stored somewhere, and will likely be accessible to the attacker. How do you overcome this problem? – amar Feb 26 '14 at 12:36
  • @amar the salt mission isn't to be "secret", the purpose is to be unique so when an attacker "try a password" with that known salt it can only compare the generated pass with this one original hash because all other passwords will have different hashes. If you don't use a hash then you can hash the password "rabbit" once and you will probably find an user with that password (you hash only 1 time and then compare it thousand times), if you use a salt then you will have to hash "rabbit" + salt for every user and compare it (thousands hashes with thousands comparisons). – kiBytes Feb 26 '14 at 13:35
1

A salt is used to:

  1. avoid attacks through precomputed rainbow tables.
  2. map the same password to different hashes.

A salt should be random and sufficiently long (e.g. random 128 bits) so that its entropy becomes large because only a salt with a big entropy can avoid attacks through rainbow tables.

Usually, there is no reason to derive the salt from some of the user's attributes, e.g. the password or username. A scheme for password hashing which is commonly used in practice is bcrypt. The Java implementation of bcrypt I'm aware (see) of automatically creates a random salt for each password. The salt is part of the bcrypt hash so that you don't have to handle the salt in any special way. The implementation also provides methods to check passwords which automatically decomposes the bcrypt hash into its salt and the actual password hash.

Bcrypt also offers a load factor to increase the complexity required to compute a hash. This is useful to avoid brute force attacks because it thwarts an attacker to compute a large number of hashes.

Altogether there is really no reason why to implement your own scheme for password hashing.

1

Please read How to securely hash passwords? - you should not roll your own. @ThomasPornin has a great answer to that question, and the section on Salt Generation includes (among a lot more good advice) the following wisdom:

The main and only point of the salt is to be as unique as possible. Whenever a salt value is reused anywhere, this has the potential to help the attacker.

For instance, if you use the user name as salt, then an attacker (or several colluding attackers) could find it worthwhile to build rainbow tables which attack the password hashing function when the salt is "admin" (or "root" or "joe") because there will be several, possibly many sites around the world which will have a user named "admin". Similarly, when a user changes his password, he usually keeps his name, leading to salt reuse. snip

The cheap way to obtain uniqueness is to use randomness. If you generate your salt as a sequence of random bytes from the cryptographically secure PRNG that your operating system offers (/dev/urandom, CryptGenRandom()...) then you will get salt values which will be "unique with a sufficiently high probability". 16 bytes are enough so that you will never see a salt collision in your life, which is overkill but simple enough. snip

Essentially, you cannot use the password to generate a salt for the password, since the ONLY input is the password!

  • Thus, an attacker still need only put "123456" into their hash generator once, and then they'll find all the thousands of users who used that as their password. If you had random salts, they'd have to try thousands of times (once per salt + password combination) to get those thousands of weak passwords.

You should use a random number generator to generate unique, per-user salts (and store them in plaintext in the database, along with the password hash and number of iterations or work factor used [so you can easily increase it later]), and the general advice here is for roughly a 16 byte random salt. 8 bytes is probably a practical minimum for length of the salt.

Not the answer you're looking for? Browse other questions tagged or ask your own question.