salted password online hashed and security database-design authentication hash passwords

security - password - Hash de contraseña: ¿cómo actualizar?



salt password generator (6)

Espere hasta que su usuario inicie sesión (para que tenga la contraseña en texto plano), luego cópiela con el nuevo algoritmo y guárdela en su base de datos.

Hay mucha discussion sobre el mejor algoritmo, pero ¿y si ya estás en producción? ¿Cómo se actualiza sin tener que reiniciar en el usuario?

EDITAR / DESCARGO DE RESPONSABILIDAD: Aunque originalmente quería una solución de "solución rápida" y elegí la respuesta de orip, debo admitir que si la seguridad en su aplicación es lo suficientemente importante como para preocuparse por este problema, entonces una solución rápida es la mentalidad equivocada y su propuesta la solución es probablemente inadecuada.


Probablemente no pueda cambiar el esquema de hashing de contraseña ahora, a menos que esté almacenando contraseñas en texto sin formato. Lo que puede hacer es volver a codificar las contraseñas de los miembros utilizando un mejor esquema de hash después de que cada usuario haya iniciado sesión correctamente.

Puedes intentar esto:

Primero agregue una nueva columna a su tabla de miembros, o cualquier tabla que almacene contraseñas.

ALTER TABLE members ADD is_pass_upgraded tinyint(1) default 0;

A continuación, en su código que autentica a los usuarios, agregue alguna lógica adicional (estoy usando PHP):

<?php $username = $_POST[''username'']; $password = $_POST[''password'']; $auth_success = authenticateUser($username, $password); if (!$auth_success) { /** * They entered the wrong username/password. Redirect them back * to the login page. */ } else { /** * Check to see if the member''s password has been upgraded yet */ $username = mysql_real_escape_string($username); $sql = "SELECT id FROM members WHERE username = ''$username'' AND is_pass_upgraded = 0 LIMIT 1"; $results = mysql_query($sql); /** * Getting any results from the query means their password hasn''t been * upgraded yet. We will upgrade it now. */ if (mysql_num_rows($results) > 0) { /** * Generate a new password hash using your new algorithm. That''s * what the generateNewPasswordHash() function does. */ $password = generateNewPasswordHash($password); $password = mysql_real_escape_string($password); /** * Now that we have a new password hash, we''ll update the member table * with the new password hash, and change the is_pass_upgraded flag. */ $sql = "UPDATE members SET password = ''$password'', is_pass_upgraded = 1 WHERE username = ''$username'' LIMIT 1"; mysql_query($sql); } }

Su función authenticateUser () debería cambiarse a algo similar a esto:

<?php function authenticateUser($username, $password) { $username = mysql_real_escape_string($username); /** * We need password hashes using your old system (md5 for example) * and your new system. */ $old_password_hashed = md5($password); $new_password_hashed = generateBetterPasswordHash($password); $old_password_hashed = mysql_real_escape_string($old_password_hashed); $new_password_hashed = mysql_real_escape_string($new_password_hashed); $sql = "SELECT * FROM members WHERE username = ''$username'' AND ( (is_pass_upgraded = 0 AND password = ''$old_password_hashed'') OR (is_pass_upgraded = 1 AND password = ''$new_password_hashed'') ) LIMIT 1"; $results = mysql_query($sql); if (mysql_num_rows($results) > 0) { $row = mysql_fetch_assoc($results); startUserSession($row); return true; } else { return false; } }

Hay ventajas y desventajas de este enfoque. En el lado positivo, la contraseña de un miembro individual se vuelve más segura después de iniciar sesión. La desventaja es que las contraseñas de todos no están aseguradas.

Solo haría esto por quizás 2 semanas. Enviaría un correo electrónico a todos mis miembros y les diría que tienen 2 semanas para iniciar sesión en su cuenta debido a las actualizaciones del sitio. Si no pueden iniciar sesión en 2 semanas, deberán usar el sistema de recuperación de contraseña para restablecer su contraseña.


Simplemente vuelve a hash el texto sin formato cuando se autentiquen la próxima vez. Oah y usa SHA-256 con una sal de base256 (byte completo) y 256 bytes de tamaño.


Una buena manera de proteger todas las contraseñas existentes: use el hash existente como entrada para el nuevo y mejor hash de contraseñas.

Entonces, si sus hashes existentes son MD5 rectos, y planea mudarse a alguna forma de PBKDF2 (o bcrypt , o scrypt ), entonces cambie su hash de contraseña a:

PBKDF2( MD5( password ) )

Ya tiene el MD5 en su base de datos, de modo que todo lo que hace es aplicarle PBKDF2.

La razón por la que esto funciona bien es que las debilidades de MD5 frente a otros valores hash (por ejemplo, SHA- *) no afectan el uso de contraseñas. Por ejemplo, sus vulnerabilidades de colisión son devastadoras para las firmas digitales, pero no afectan a los hash de contraseñas . Comparado con hashes más largos, MD5 reduce algo el espacio de búsqueda hash con su salida de 128 bits, pero esto es insignificante en comparación con el espacio de búsqueda de contraseña en sí, que es mucho más pequeño.

Lo que hace que una contraseña hash fuerte se ralentice (se logra en PBKDF2 por iteraciones) y una sal aleatoria, suficientemente larga, la MD5 inicial no afecte negativamente a ninguna de ellas.

Y mientras lo hace, agregue un campo de versión a las contraseñas también.

EDITAR : la criptografía StackExchange tiene una discusión interesante sobre este método.


Una forma de hacerlo es:

  • Introduzca un nuevo campo para la nueva contraseña
  • Cuando el usuario inicia sesión, comprueba la contraseña en contra del antiguo hash
  • Si está bien, pica la contraseña de texto sin cifrar con el nuevo hash
  • Eliminar el viejo hash

Luego, gradualmente, solo tendrás contraseñas con el nuevo hash


Una opción es hacer que su hash almacenado incluya un número de versión de algoritmo, para que comience con el algoritmo 0 (por ejemplo, MD5) y almacene

0:ab0123fe

luego, cuando actualizas a SHA-1, cambias el número de versión a 1:

1:babababa192df1312

(No, sé que estas longitudes probablemente no sean las correctas).

De esta forma, siempre se puede saber a qué versión se debe comparar al validar una contraseña. Puede invalidar algoritmos viejos simplemente limpiando hashes almacenados que comienzan con ese número de versión.

Si ya tiene hashes en producción sin un número de versión, simplemente elija un esquema para que pueda reconocer fácilmente los hash no versionados; por ejemplo, usando el esquema de dos puntos anterior, cualquier hash que no contenga dos puntos debe por definición es anterior al esquema de control de versiones, por lo que se puede deducir que es la versión 0 (o lo que sea).