Utilice siempre un algoritmo de hash de contraseña: Argon2 , scrypt , bcrypt o PBKDF2 .
Argon2 ganó el concurso de hashing de contraseñas de 2015. Scrypt , bcrypt y PBKDF2 son algoritmos más antiguos que ahora se consideran menos preferidos, pero aún son fundamentalmente sólidos, por lo que si su plataforma aún no es compatible con Argon2, está bien usar otro algoritmo por ahora.
Nunca almacene una contraseña directamente en una base de datos. Tampoco lo cifre: de lo contrario, si se viola su sitio, el atacante obtiene la clave de descifrado y puede obtener todas las contraseñas. Las contraseñas DEBEN ser hash .
Un hash de contraseña tiene propiedades diferentes de un hash de tabla hash o un hash criptográfico. Nunca use un hash criptográfico ordinario como MD5, SHA-256 o SHA-512 en una contraseña. Un algoritmo de hash de contraseña utiliza un salt , que es único (no se usa para ningún otro usuario o en la base de datos de nadie). La sal es necesaria para que los atacantes no puedan calcular previamente los valores hash de las contraseñas comunes: con una sal, tienen que reiniciar el cálculo para cada cuenta. Un algoritmo de hash de contraseña es intrínsecamente lento , tan lento como puede permitirse. La lentitud lastima al atacante mucho más que a ti porque el atacante tiene que probar muchas contraseñas diferentes. Para obtener más información, consulte Cómo contraseñas seguras de hash .
Un hash de contraseña codifica cuatro piezas de información:
- Un indicador de qué algoritmo se utiliza. Esto es necesario para la agilidad : las recomendaciones criptográficas cambian con el tiempo. Debe poder realizar la transición a un nuevo algoritmo.
- Un indicador de dificultad o dureza. Cuanto mayor sea este valor, más cálculo se necesita para calcular el hash. Esto debería ser un valor de configuración constante o global en la función de cambio de contraseña, pero debería aumentar con el tiempo a medida que las computadoras se vuelven más rápidas, por lo que debe recordar el valor de cada cuenta. Algunos algoritmos tienen un solo valor numérico, otros tienen más parámetros allí (por ejemplo, para ajustar el uso de la CPU y el uso de RAM por separado).
- La sal. Como la sal debe ser globalmente única, debe almacenarse para cada cuenta. La sal debe generarse aleatoriamente en cada cambio de contraseña.
- El hash propiamente dicho, es decir, la salida del cálculo matemático en el algoritmo de hash.
Muchas bibliotecas incluyen un par de funciones que convenientemente empaqueta esta información como una sola cadena: una que toma el indicador del algoritmo, el indicador de dureza y la contraseña, genera una sal aleatoria y devuelve la cadena hash completa; y uno que toma una contraseña y la cadena hash completa como entrada y devuelve un booleano que indica si la contraseña era correcta. No hay un estándar universal, pero una codificación común es
$ algoritmo $ parámetros $ salt $ salida
donde algorithm
es un número o una cadena alfanumérica corta que codifica la elección del algoritmo, parameters
es una cadena imprimible salt
y output
está codificada en Base64 sin terminar=
.
16 bytes son suficientes para la sal y la salida. (Ver, por ejemplo, recomendaciones para Argon2 .) Codificado en Base64, son 21 caracteres cada uno. Las otras dos partes dependen del algoritmo y los parámetros, pero son típicos de 20 a 40 caracteres. Eso es un total de aproximadamente 82 caracteres ASCII ( CHAR(82)
y no es necesario usar Unicode), a lo que debe agregar un margen de seguridad si cree que será difícil ampliar el campo más adelante.
Si codifica el hash en formato binario, puede reducirlo a 1 byte para el algoritmo, 1-4 bytes para la dureza (si codifica algunos de los parámetros) y 16 bytes cada uno para la sal y la salida , para un total de 37 bytes. Digamos 40 bytes ( BINARY(40)
) para tener al menos un par de bytes de repuesto. Tenga en cuenta que estos son bytes de 8 bits, no caracteres imprimibles, en particular el campo puede incluir bytes nulos.
Tenga en cuenta que la longitud del hash no tiene ninguna relación con la longitud de la contraseña.