Estoy pensando en implementar un esquema de reciclaje de sal en mi base de datos de credenciales de usuario. La motivación detrás de esta decisión es que incluso si el atacante consigue poner sus manos en la base de datos y tiene tiempo suficiente para descifrar una contraseña o dos, en el momento en que lo haga, la sal se habrá restablecido y su Los resultados serán inútiles.
Mi código de registro de usuario actual es el siguiente (pseudocódigo de PHP):
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);
Lo que me propongo hacer es, en lugar de simplemente cambiar el factor para mantenerse al día con la ley de Moore, también cambiar la sal cada pocos días más o menos. Por supuesto, eso solo beneficiaría a los usuarios regulares que inician sesión cada dos días. En código:
if(today() - getLastLogin() > $SALT_CHANGE_THRESHOLD || /*work factor increased*/)
setPass($username, getSalt($username), $plainpass); //as above
Mis preguntas:
- ¿Con qué frecuencia debe cambiar una sal? Estoy tentado a hacerlo todos los días, pero me preocupa que pueda ser un poco excesivo
- ¿Es suficiente con cambiar la sal sin restablecer la contraseña cada dos meses? No lo implementaré porque sé que a los usuarios les resulta molesto, y puede obligarlos a seleccionar una contraseña que luego puedan olvidar.
Como dije anteriormente, los usuarios que no regresan no se beneficiarán de esto. Los usuarios que usan la misma contraseña con otro servicio comprometido tampoco se beneficiarán, pero eso no me preocupa.
También estoy muy tentado de usar la lista de contraseñas más comunes y evitar que los usuarios seleccionen cualquiera de ellos para evitar el uso de contraseñas comprometidas (aunque el uso de todos los 10000 es un poco extremo).