Cómo usar password_hash de PHP para hash y verificar contraseñas
Recientemente he estado intentando implementar mi propia seguridad en un script de inicio de sesión que encontré en Internet. Después de luchar por aprender a crear mi propio script para generar salt para cada usuario, me topé con password_hash
.
Por lo que tengo entendido (según la lectura de esta página ), la sal ya se genera en la fila cuando se usa password_hash
. ¿Es esto cierto?
Otra pregunta que tuve fue, ¿no sería inteligente tener 2 sales? ¿Uno directamente en el archivo y otro en la base de datos? De esa manera, si alguien compromete su sal en la base de datos, ¿aún tendrá la que está directamente en el archivo? Leí aquí que almacenar sales nunca es una buena idea, pero siempre me confundió lo que la gente quería decir con eso.
Usar password_hash
es la forma recomendada de almacenar contraseñas. No los separe en bases de datos y archivos.
Digamos que tenemos la siguiente entrada:
$password = $_POST['password'];
Primero hash la contraseña haciendo esto:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
Luego vea el resultado:
var_dump($hashed_password);
Como puede ver, está hash. (Supongo que hiciste esos pasos).
Ahora almacena esta contraseña hash en su base de datos, asegurándose de que la columna de contraseña sea lo suficientemente grande como para contener el valor hash (al menos 60 caracteres o más) . Cuando un usuario solicita iniciar sesión, verifica la entrada de la contraseña con este valor hash en la base de datos, haciendo esto:
// Query the database for username and password
// ...
if(password_verify($password, $hashed_password)) {
// If the password inputs matched the hashed password in the database
// Do something, you know... log them in.
}
// Else, Redirect them back to the login page.
Referencia oficial
Sí, lo entendiste correctamente, la función contraseña_hash() generará un salt por sí solo y lo incluirá en el valor hash resultante. Almacenar la sal en la base de datos es absolutamente correcto, hace su trabajo incluso si se conoce.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);
La segunda sal que mencionaste (la que está almacenada en un archivo) es en realidad una pimienta o una clave del lado del servidor. Si lo agrega antes del picadillo (como la sal), entonces agrega pimienta. Sin embargo, hay una manera mejor: primero puede calcular el hash y luego cifrarlo (bidireccionalmente) con una clave del lado del servidor. Esto le da la posibilidad de cambiar la clave cuando sea necesario.
A diferencia de la sal, esta clave debe mantenerse en secreto. La gente suele mezclarlo e intentar ocultar la sal, pero es mejor dejar que la sal haga su trabajo y añadir el secreto con una llave.
Sí, es verdad. ¿Por qué dudas de las preguntas frecuentes de php sobre la función? :)
El resultado de correr password_hash()
tiene cuatro partes:
- el algoritmo utilizado
- parámetros
- sal
- hash de contraseña real
Como puedes ver, el hash es parte de esto.
Claro, podría tener una sal adicional para una capa adicional de seguridad, pero honestamente creo que eso es excesivo en una aplicación PHP normal. El algoritmo bcrypt predeterminado es bueno, y podría decirse que el algoritmo Blowfish opcional es incluso mejor.