25

Assume a password storage scheme using a computationally-expensive hash algorithm and a CSPRNG salt. User ID, salt, and hash value are stored in a table; if the table is compromised, all three values are available to an adversary.

Is there any value in computing a new salt when a user changes his password?

(I think this question only makes sense if the adversary has before and after copies of the password table, but I could be very wrong about that.)

otus
  • 32,462
  • 5
  • 75
  • 167
Bob Brown
  • 353
  • 3
  • 12

3 Answers3

26

If the attacker had already begun creating a rainbow table or is engaged in some other attack which requires knowledge of the salt, then a password change with a salt change will require the attacker to start from scratch.

Always assume the attacker has before and after copies of the password hash and salt.

If the salt is not changed, any work the attacker has done may still be applicable to the new password. It may even mean the new password is already in the rainbow table or has been cracked in some other way.

Richie Frame
  • 13,278
  • 1
  • 26
  • 42
6

If the existing salt is random (and chosen from a large enough space), there is little or no benefit to changing the salt each time the user changes their password. There's no downside -- you might as well change the salt each time the user changes their password; that is probably good practice -- but if you don't change the salt, it's unlikely that anything terrible will happen.

Changing the salt doesn't help stop rainbow table attacks, because there's nothing to stop. Rainbow tables already don't work if you have a random salt for each account (assuming the salt is chosen from a large enough space). Rainbow table attacks are about amortizing work across many different accounts; they're also about precomputation, where you do some work in advance before you know any of the password hashes. If you have a random salt for each account, it is likely that each account has a different salt, so there is no opportunity to amortize work across multiple accounts; thus, if each account has a different salt, rainbow attacks are useless -- they are no better than exhaustive search.

The scenario that password hashing is designed to mitigate is where the password database is breached and the attackers learn everything stored in it (all the salts, all the password hashes). Normally this happens once, at a single point in time. In this answer, I am assuming we are talking about mitigating that kind of threat; the threat of multiple password breaches is a mostly theoretical concern that's largely irrelevant. So, all that matters is what the value of the salt and password hashes at that point in time are. Past values don't matter, because the attacker won't get to see them (assuming the password database is breached once).

So, assuming you chose salts properly in the first place, there is not much reason to change the salt each time the user logs on. For any attack that can be done if you don't change the salt, there is a variant of that attack that's at least as fast and that can be done if you do change the salt.


Of course, if you were worried that your password database might get breached multiple times, the answer would be different: then re-using the same salt for the same account could help the attacker a bit, if the user has changed their password in between the two breaches. But if you think there is a significant likelihood that your password database might get breached, you probably have more serious problems, and maybe you need to do a lot more than tweak how you generate salts.

There is a good reason to change the password salts every time that the password database is breached. One way to accomplish this is to force users to change their password any time that the password database is breached, and write your code to change the salt each time a user changes their password. So, in some sense this is an indirect argument for changing the salt each time the user changes their password. But it's really only relevant if you think your password database might be breached multiple times.

Bottom line: if you are writing code to handle password changes, it would be reasonable to pick a new salt every time, because it's easy to do. But if you run across code that doesn't change the salt every time the user changes their password, don't panic; at worst, that's a low severity issue, and in practice, it probably doesn't matter much.

D.W.
  • 36,982
  • 13
  • 107
  • 196
4

To sum up and expand on the previous answers and comments, if everything goes to plan salts may only need to be distinct, but in practice there are attacks that can be avoided by always generating a new salt whenever the password is changed.

  1. If an attacker gets access to multiple different password hashes with the same salt (due to multiple compromises or e.g. the old hash still being in backups), they can attack those simultaneously in less time than otherwise expected. There are multiple reasons this is a bad thing:

    • The old passwords may still have value. They may have been used by the user on other accounts, even if that's not good practice.
    • Some users reuse parts of a password (or include a semi-secret "pepper"). Cracking the earlier password could then allow a faster attack on the new one.
  2. If the attacker knows the salt, they can start a targeted attack before the user has even picked the password. This could come about due to an earlier compromise and a subsequent password change, or the salt could be public information (e.g. in some PAKE protocols). The attacker could then have done most of the work by the time they manage to compromise the password hash. By having the salt change on each password change you force the attacker to restart the attack whenever the user changes passwords.

Of course, these attacks are not possible with truly secure passwords of e.g. 100 bits of entropy. However, if you assumed that, you wouldn't need to use a slow password hash either. In practice many users will choose poor passwords and even those should be protected as far as practical.

otus
  • 32,462
  • 5
  • 75
  • 167