Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

One of the typical approaches to computing a salted hash is this:

hash(salt+hash(secret))

where hash is something like SHA-256 hash function - taking any size input and returning fixed size output. What's the need for the hash(secret)?

Why can't I just do this:

hash(salt + secret)

where + is simply concatenating two byte arrays?

share|improve this question
1  
I don't see any reason here. Do you have some examples where it is used this way? –  Paŭlo Ebermann Jun 9 '12 at 12:44
    
@Paŭlo Ebermann: I've seen in multiple times in comments to a post about recent LinkedIn passwords leakage. –  sharptooth Jun 9 '12 at 12:46
2  
The only reason I can think of is for hiding the clear text password on the network. Consider that with $H(salt || pwd)$, in a very simple system, the user would send $pwd$ and the server would compute the hash to check. Anybody who can sniff the password from the network now cannot only log in, but also knows the password. With $H(salt || H(pwd))$ he can only sniff the hash. He can now log in, but would still need a preimage attack to find out the actual password. –  Maeher Jun 9 '12 at 12:56
    
LinkedIn did not know the secret, they only knew hash_without_salt(secret). That's what they stored in their database. So unless they waited for every person to login, the only way to add a salt, is to take the stored unsalted hash as input. –  Hendrik Brummermann Jun 11 '12 at 14:30
add comment

1 Answer

This construction has two advantages over a plain hash of param1||param2:

  • It's immune to length-extensions
  • You can't get collisions of the form param1=A||B param2=C vs. param1=A param2=B||C.

But neither of those is relevant to password hashing, so it doesn't offer any advantage there.

The construction looks like it's inspired by HMAC:

$$ HMAC(K,m) = H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ m)) $$


But of course for password hashing one would not use such fast hashing constructions. Correct choices are scrypt, bcrypt, and PBKDF2. These have a designated salt parameter, so they don't need such an ad-hoc construction to mix salt and password.


This system has one big advantage though: You can upgrade existing hashes to it, without knowing the plaintext password. Essentially you treat $ hash(pass) $ as the new password. When upgrading an old system from a plain, unsalted hash, I'd use something like:

$ PBKDF2(LegacyHash(password), salt) $

share|improve this answer
    
A negation is missing in the first sentence of the last paragraph. –  fgrieu Jun 9 '12 at 13:03
    
right. Thanks.. –  CodesInChaos Jun 9 '12 at 13:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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