Hay un montón de excelentes publicaciones sobre seguridad de contraseñas en bases de datos de desbordamiento de pila y en otros sitios y, como soy completamente nuevo en esto, pasé algunas horas intentando aprender más sobre esto en los últimos días. Sin embargo, hay tantas sugerencias y mejores prácticas que me confundí ...
Además, todavía hay muchas publicaciones más antiguas de 2007-2010, etc. Como he visto la rapidez con que cambian las cosas, no estoy seguro de que esto todavía sea común para usarlo como sugieren. Entonces, quería resumir lo que encontré en las publicaciones y luego preguntar si este método que encontré fue una buena práctica ...
Entonces, esto no es una guía, sino un resumen, sé que es muy básico y si hay errores, ¡corríjame!
- Solo para mencionar: nunca debe almacenar contraseñas de texto simple :)
- Tienes contraseñas hash "unidireccionales" para que nadie pueda ver el texto sin formato. Cuando el usuario ingresa la contraseña, la hash de la misma manera y la comparas con el paso de hash en la base de datos.
- Además del hash de una contraseña, debes agregarla. Usted agrega el salt a la cadena de contraseña simple y hash a la nueva cadena. Si la contraseña simple es débil, agregar la sal la hace más larga y fuerte.
- Además, la sal debería ser aleatoria (he leído que el término "sal" significa que es aleatorio de todos modos, de lo contrario, ¿se llamaba "clave"?). Esto es para evitar ataques de la tabla arco iris, porque el atacante tendría que crear una tabla para cada sal, lo que es mucho más costoso en términos de tiempo, etc. Además, si dos usuarios tienen la misma contraseña, no la reconocerá si usa sales al azar.
- ¡La sal no es un secreto! Se está almacenando en la base de datos junto a la contraseña de hash. Sin embargo, puede que no sea la mejor idea usar una marca de tiempo, la dirección de correo electrónico del usuario o cualquier otra cosa conectada al usuario como un sal aleatorio. Como una razón es por ejemplo mencionó que los usuarios tienden a usar las mismas contraseñas en múltiples sitios / servicios. Por lo tanto, la sal debe ser una cadena aleatoria, la mejor lectura sería de 64 bits.
- El siguiente paso es agregar una iteración al proceso de hashing (1000 o más bucles), para que el salt se agregue a la contraseña y luego se repitan una y otra vez, lo que significa que solo una fracción de segundo para el usuario espere al iniciar sesión, pero se resume si tiene aproximadamente 10.000 entradas en su base de datos.
- Podría ser un pequeño beneficio, si agrega una clave de sitio, almacenada, por ejemplo. como una var global además de la sal. Sin embargo, siempre debe suponer que los atacantes también tienen acceso a su sistema de archivos.
- Algoritmos de hash: he comprobado que ya no es seguro usar MD5, SHA1 y otros métodos débiles ...
Entonces, hay diferentes opiniones sobre si usar SHA256, SHA512? ¿Deberías usar hash_hmac? Algunos dicen que sí: ( enlace ) algunos dicen usar bibliotecas es la única manera segura ... y luego una o dos veces en una publicación que he leído para no usar bibliotecas como bcrypt o bubble fish ??
¿Es realmente necesario usar una biblioteca o es, por ejemplo, un método como este es suficiente:
function hash_password($password, $nonce) {
for ($i = 0; $i < 5000; $i++) {
$hashed_pass = hash_hmac('sha512', $hashed_pass . $nonce . $password, $site_key);
}
return $hashed_pass;
}
Mucha gente dice que no inventes tu propio algo, así que estoy un poco asustado solo por usar cualquier cosa inventada por mí mismo.
Puedo imaginar que es difícil de predecir, pero ¿por cuánto tiempo se puede considerar que un método usado hoy en día es lo suficientemente seguro?
ACTUALIZACIÓN: Gracias por todos sus comentarios excelentes. Falta un punto principal, como veo y muchos de ustedes dijeron: seguridad de contraseña, lo que significa que una contraseña segura es la básica. Creo que recibí el mensaje, gracias de nuevo! :)
ACTUALIZACIÓN 2: para completar, he encontrado el siguiente código en enlace que utilizo para generar una sal aleatoria:
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!§$%&/().-:;_#+*[]{}=";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
$random_salt= rand_string(20);