I'm thinking of implementing a salt recycling scheme on my user credentials database. The motivation behind this decision is that even if the attacker manages to get his hands on the database and has enough time to crack a password or two, by the time he does the salt will have been reset and his results will be useless.
My current user registration code is the following (PHP-flavored pseudocode):
function getSalt($username){
$salt=$username.getFromUrandom($SALT_RANDOM_READ); //64 bytes
$salt=sha256($salt);
return $salt;
}
function setPass($username, $salt, $pass){
$pass=bcrypt($BCRYPT_WORK_FACTOR, $pass, $salt); //factor is set to 8 for now
store_to_db($username, $pass);
}
setPass($username, getSalt($username), $plainpass);
What I propose to do is, instead of merely changing the factor to keep up with Moore's law, also change the salt every few days or so. Of course that would only benefit regular users who login every couple of days. In code:
if(today() - getLastLogin() > $SALT_CHANGE_THRESHOLD || /*work factor increased*/)
setPass($username, getSalt($username), $plainpass); //as above
My questions:
- How often should a salt change? I'm tempted to do it daily but I'm worried it might be a bit of an overkill
- Is changing the salt enough to do without a password reset every couple of months? I won't be implementing that because I know users find it annoying, and it may force them to select a password they might later forget.
As I said above, non-returning users will not benefit from this. Users who use the same password with another compromised service will also not benefit but I'm not worried about that.
I'm also very tempted to use the most common passwords list and prevent users from selecting any of them in order to protect from using compromised passwords (although using all 10000 is a bit extreme).