# What's the reason for applying the hash twice when hashing with salt?

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?

-
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
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

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)$

-
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