Pregunta

No estoy seguro de cómo funciona el hash de contraseñas (lo implementaré más adelante), pero necesito crear un esquema de base de datos ahora.

Estoy pensando en limitar las contraseñas a 4-20 caracteres, pero según entiendo, después de cifrar la cadena de hash tendrá una longitud diferente.

Entonces, ¿cómo almacenar estas contraseñas en la base de datos?

¿Fue útil?

Solución

Actualización: el simple hecho de usar una función hash no es lo suficientemente fuerte para almacenar contraseñas. Debería leer la respuesta de Gilles en este hilo para obtener una explicación más detallada.

Para contraseñas, use un algoritmo hash de fortalecimiento de clave como Bcrypt o Argon2i. Por ejemplo, en PHP, use la función password_hash () , que utiliza Bcrypt de forma predeterminada.

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

El resultado es una cadena de 60 caracteres similar a la siguiente (pero los dígitos variarán porque genera una sal única).

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Utilice el tipo de datos SQL CHAR (60) para almacenar esta codificación de un hash Bcrypt. Tenga en cuenta que esta función no se codifica como una cadena de dígitos hexadecimales, por lo que no podemos fácilmente descifrarla para almacenarla en binario.

Otras funciones hash todavía tienen usos, pero no para almacenar contraseñas, así que mantendré la respuesta original a continuación, escrita en 2008.


Depende del algoritmo de hash que uses. El hash siempre produce un resultado de la misma longitud, independientemente de la entrada. Es típico representar el resultado de hash binario en texto, como una serie de dígitos hexadecimales. O puede usar UNHEX () para reducir una cadena de dígitos hexadecimales a la mitad.

  • MD5 genera un valor hash de 128 bits. Puedes usar CHAR (32) o BINARY (16)
  • SHA-1 genera un valor hash de 160 bits. Puedes usar CHAR (40) o BINARY (20)
  • SHA-224 genera un valor hash de 224 bits. Puede utilizar CHAR (56) o BINARY (28)
  • SHA-256 genera un valor hash de 256 bits. Puede utilizar CHAR (64) o BINARY (32)
  • SHA-384 genera un valor hash de 384 bits. Puede utilizar CHAR (96) o BINARY (48)
  • SHA-512 genera un valor hash de 512 bits. Puede utilizar CHAR (128) o BINARY (64)
  • BCrypt genera un valor de hash de 448 bits que depende de la implementación. Es posible que necesite CHAR (56), CHAR (60), CHAR (76), BINARY (56) o BINARY (60)

A partir de 2015, NIST recomienda usar SHA-256 o superior para cualquier aplicación de funciones hash que requieran interoperabilidad. Pero NIST no recomienda usar estas funciones hash simples para almacenar contraseñas de forma segura.

Los algoritmos de hashing menores tienen sus usos (como los internos de una aplicación, no para el intercambio), pero son conocido como crackeable .

Otros consejos

Puede usar CHAR (longitud de hash) para definir su tipo de datos para MySQL porque cada algoritmo de hash siempre evaluará el mismo número de caracteres. Por ejemplo, SHA1 siempre devuelve un número hexadecimal de 40 caracteres.

Puede encontrar este artículo de Wikipedia sobre la salazón que vale la pena . La idea es agregar un conjunto de datos para aleatorizar el valor de hash; esto protegerá sus contraseñas de ataques de diccionario si alguien obtiene acceso no autorizado a los hashes de contraseñas.

Como una cadena de longitud fija (VARCHAR (n) o como MySQL la llama). Un hash siempre tiene una longitud fija de, por ejemplo, 12 caracteres (dependiendo del algoritmo de hash que use). Por lo tanto, una contraseña de 20 caracteres se reduciría a un hash de 12 caracteres, y una contraseña de 4 caracteres también generaría un hash de 12 caracteres.

Siempre use un algoritmo de hashing de contraseña: Argon2 , scrypt , bcrypt o PBKDF2 .

Argon2 ganó la competencia de hashing de contraseñas de 2015. Scrypt , bcrypt y PBKDF2 son algoritmos más antiguos que son Se considera menos preferido ahora, pero sigue siendo fundamental, 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 encripte: de lo contrario, si su sitio se rompe, el atacante obtiene la clave de descifrado y puede obtener todas las contraseñas. Las contraseñas DEBEN estar 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 hashing de contraseña utiliza un salt , que es único (no se usa para ningún otro usuario ni en la base de datos de nadie más). La sal es necesaria para que los atacantes no puedan simplemente calcular previamente los hashes de las contraseñas comunes: con una sal, tienen que reiniciar el cálculo para cada cuenta. Un algoritmo de hashing de contraseña es intrínsecamente lento & # 8212; & nbsp; tan lento como puede permitirse. La lentitud duele 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 cifrar de forma segura las contraseñas .

Un hash de contraseña codifica cuatro datos:

  • Un indicador de qué algoritmo se utiliza. Esto es necesario para 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 más alto sea este valor, más cálculo se necesita para calcular el hash. Esto debería ser una constante o un valor de configuración 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 CPU y RAM por separado).
  • La sal. Dado que la sal debe ser globalmente única, debe almacenarse para cada cuenta. La sal se debe generar aleatoriamente en cada cambio de contraseña.
  • El hash adecuado, es decir, la salida del cálculo matemático en el algoritmo de hash.

Muchas bibliotecas incluyen un par de funciones que empaquetan convenientemente esta información como una sola cadena: una que toma el indicador de algoritmo, el indicador de dureza y la contraseña, genera un salt aleatorio y devuelve la cadena de hash completa; y uno que toma una contraseña y la cadena de hash completa como entrada y devuelve un valor booleano que indica si la contraseña era correcta. No hay un estándar universal, pero una codificación común es

$algorithm$parameters$salt$output

donde algorithm es un número o una cadena alfanumérica corta que codifica la elección del algoritmo, parameters es una cadena imprimible, y salt y output están codificados en Base64 sin terminar = .

16 bytes son suficientes para la sal y la salida. (Ver, por ejemplo, recomendaciones para Argon2 .) Codificado en Base64, eso es 21 personajes cada uno. Las otras dos partes dependen del algoritmo y los parámetros, pero 20 y # 8211; 40 caracteres son típicos. Eso es un total de cerca de 82 caracteres ASCII ( CHAR (82) , y no es necesario Unicode), a los que debe agregar un margen de seguridad si cree que será Difícil ampliar el campo más tarde.

Si codifica el hash en un formato binario, puede reducirlo a 1 byte para el algoritmo, 1 & # 8211; 4 bytes para la dureza (si codifica algunos de los parámetros), y 16 bytes cada uno Para la sal y salida, para un total de 37 bytes. Diga 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 relación alguna con la longitud de la contraseña.

Realmente depende del algoritmo de hash que estés usando. La longitud de la contraseña tiene poco que ver con la longitud del hash, si recuerdo correctamente. Busque las especificaciones en el algoritmo de hash que está utilizando, ejecute algunas pruebas y trunque justo por encima de eso.

Los hash son una secuencia de bits (128 bits, 160 bits, 256 bits, etc., según el algoritmo). Su columna debe ser de tipo binario, no de texto / carácter, si MySQL lo permite (el tipo de datos de SQL Server es binario (n) o varbinary (n) ). También debes poner sal a los hashes. Las sales pueden ser de texto o binarias, y necesitará una columna correspondiente.

Debería usar TEXT (almacenar un número ilimitado de caracteres) por razones de compatibilidad hacia adelante. Los algoritmos de hash (necesitan) se vuelven más fuertes con el tiempo y, por lo tanto, este campo de base de datos tendrá que admitir más caracteres con el tiempo. Además, dependiendo de su estrategia de migración, es posible que necesite almacenar hashes nuevos y antiguos en el mismo campo, por lo que no se recomienda fijar la longitud a un tipo de hash.

Siempre he probado para encontrar la longitud de cadena MAX de una cadena encriptada y establecerla como la longitud de caracteres de un tipo VARCHAR. Dependiendo de cuántos registros tengas, realmente podría ayudar al tamaño de la base de datos.

para md5 vARCHAR (32) es apropiado. Para aquellos que usan AES es mejor usar varbinary.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top