2009-03-05 51 views
138

Tengo una pregunta simple que se produjo cuando quería para almacenar el resultado de un hash SHA1 en una base de datos MySQL:valores hash Almacenamiento SHA1 en MySQL

¿Cuánto tiempo debe ser el campo VARCHAR en el que almacenar el resultado hash?

+8

Si sólo googled sha1 clic im tener suerte y que debe estar en la wikipedia, donde puedes encontrar es siempre 160 bits. –

Respuesta

283

Utilizaría VARCHAR para datos de longitud variable, pero no con datos de longitud fija. Como un valor de SHA-1 es siempre de 160 bits de largo, el VARCHAR simplemente desperdicia an additional byte for the length of the fixed-length field.

Y tampoco almacenaría el valor que devuelve el SHA1. Porque usa solo 4 bits por carácter y, por lo tanto, necesitaría 160/4 = 40 caracteres. Pero si usa 8 bits por carácter, solo necesitaría un campo de 160/8 = 20 caracteres de largo.

Así que le recomiendo que use BINARY(20) y UNHEX function para convertir el valor SHA1 en binario.

He comparado los requisitos de almacenamiento para BINARY(20) y CHAR(40).

CREATE TABLE `binary` (
    `id` int unsigned auto_increment primary key, 
    `password` binary(20) not null 
); 
CREATE TABLE `char` (
    `id` int unsigned auto_increment primary key, 
    `password` char(40) not null 
); 

Con millones de registros binary(20) toma 44.56M, mientras char(40) toma 64.57M. InnoDB motor.

+2

En PostgreSQL, esto se traduciría en el uso de un campo bytea, ¿verdad? – mvexel

+9

@Gumbo: ¡Usted señor, creo, ha hecho esto antes! :) –

+0

La solución es genial, pero hay otro punto para usar char (40) con sha1 hexagonal: esto es mucho más utilizado, y habrá menos problemas de conversión en un código de aplicación. –

36

¡Un hash SHA1 tiene 40 caracteres de largo!

+80

En codificación hexadecimal ... –

6

El tamaño de salida de sha1 es de 160 bits. Que es 160/8 == 20 caracteres (si usa caracteres de 8 bits) o 160/16 = 10 (si usa caracteres de 16 bits).

+0

Suponiendo caracteres binarios de 8 bits. 40 caracteres si está almacenado como hex. – Tyzoid

3

Por lo tanto, la longitud es entre 10 caracteres de 16 bits y 40 dígitos hexadecimales.

En cualquier caso, decida el formato que va a almacenar y establezca el campo en un tamaño fijo según ese formato. De esa manera no tendrá ningún espacio desperdiciado.

2

Es posible que desee utilizar VARCHAR en los casos en que no siempre almacene un hash para el usuario (es decir, autenticar cuentas/olvidó la URL de inicio de sesión). Una vez que un usuario ha autenticado/cambiado su información de inicio de sesión, no debería poder usar el hash y no debería tener ninguna razón para hacerlo. Podría crear una tabla separada para almacenar hash temporal -> asociaciones de usuarios que podrían eliminarse, pero no creo que la mayoría de la gente se moleste en hacer esto.

2

Si necesita un índice en la columna sha1, sugiero CHAR (40) por motivos de rendimiento. En mi caso, la columna sha1 es un token de confirmación de correo electrónico, por lo que en la página de destino la consulta solo se ingresa con el token. En este caso, CHAR (40) con INDEX, en mi opinión, es la mejor opción :)

Si desea adoptar este método, recuerde dejar $ raw_output = false.

+1

¿Por qué no indexar BINARY (20)? ¿No sería tan rápido y la mitad de grande? – nickdnk

+0

Bueno, esto ~ hace 5 años, pero creo que me refería al hecho de que todavía necesita unhex que agrega algo de carga (+ hace que la aplicación sea más difícil de mantener y menos portátil?). Depende también de tu hardware, si tienes menos espacio de almacenamiento y es lento, probablemente también sea mejor quedarse con el binario (20); de lo contrario, diría que es char (40). Difícil de decir sin realizar algunas pruebas con el idioma y el hardware que usaría y ver qué le conviene más. –

+1

Supongo que si estás haciendo algo diferente de seleccionar desde unhex (hash) = hash para buscar una sola fila, entonces quizás tengas razón. Pero mantener el índice almacenado en memoria intermedia llevará el doble de memoria de esta manera. – nickdnk

8

Reference taken from this blog:

A continuación se muestra una lista de algoritmo de hash, junto con su tamaño requiere poco:

  • MD5 = valor hash de 128 bits.
  • SHA1 = valor hash de 160 bits.
  • SHA224 = valor hash de 224 bits.
  • SHA256 = valor hash de 256 bits.
  • SHA384 = valor hash de 384 bits.
  • SHA512 = valor hash de 512 bits.

Creado mesa de una muestra con requieren CHAR (n):

CREATE TABLE tbl_PasswordDataType 
(
    ID INTEGER 
    ,MD5_128_bit CHAR(32) 
    ,SHA_160_bit CHAR(40) 
    ,SHA_224_bit CHAR(56) 
    ,SHA_256_bit CHAR(64) 
    ,SHA_384_bit CHAR(96) 
    ,SHA_512_bit CHAR(128) 
); 
INSERT INTO tbl_PasswordDataType 
VALUES 
(
    1 
    ,MD5('SamplePass') 
    ,SHA1('SamplePass') 
    ,SHA2('SamplePass',224) 
    ,SHA2('SamplePass',256) 
    ,SHA2('SamplePass',384) 
    ,SHA2('SamplePass',512) 
); 
+5

Por favor, _por favor_, _ ** por favor ** _ en realidad no almacena contraseñas como esta. –

+0

Hey berry, ¿puedes explicar tu POR QUÉ?en detalles – Anvesh

+2

Almacenar hash de contraseñas simples hace que sea mucho más fácil que las contraseñas sean "extraídas" si su base de datos está comprometida que si utiliza un hash de contraseña salado (con suerte extendido). Lectura sugerida: https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016 – matt