Stockage des valeurs de hachage SHA1 dans MySQL

J’ai une question simple qui s’est posée quand j’ai voulu stocker le résultat d’un hachage SHA1 dans une firebase database MySQL:

Combien de temps le champ VARCHAR doit-il contenir le résultat du hachage?

J’utiliserais VARCHAR pour les données de longueur variable, mais pas pour les données de longueur fixe. Comme une valeur SHA-1 est toujours longue de 160 bits, le VARCHAR ne ferait que perdre un octet supplémentaire pour la longueur du champ de longueur fixe .

Et je ne voudrais pas non plus stocker la valeur que SHA1 retourne. Parce qu’il utilise seulement 4 bits par caractère et qu’il faudrait donc 160/4 = 40 caractères. Mais si vous utilisez 8 bits par caractère, vous n’auriez besoin que d’un champ de 160/8 = 20 caractères.

Je vous recommande donc d’utiliser BINARY(20) et la fonction UNHEX pour convertir la valeur SHA1 en binary.

J’ai comparé les besoins de stockage pour BINARY(20) et 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 ); 

Avec des millions d’enregistrements, le binary(20) prend 44,56M, tandis que le char(40) prend 64,57M. Moteur InnoDB .

Un hash SHA1 fait 40 caractères de long!

Référence tirée de ce blog:

Vous trouverez ci-dessous une liste de l’algorithme de hachage avec sa taille de bit requirejse:

  • MD5 = valeur de hachage de 128 bits.
  • SHA1 = valeur de hachage de 160 bits.
  • SHA224 = valeur de hachage de 224 bits.
  • SHA256 = Valeur de hachage de 256 bits.
  • SHA384 = valeur de hachage de 384 bits.
  • SHA512 = Valeur de hachage de 512 bits.

Création d’un exemple de table avec obligatoire 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_WithAddedSalt') ,SHA1('SamplePass_WithAddedSalt') ,SHA2('SamplePass_WithAddedSalt',224) ,SHA2('SamplePass_WithAddedSalt',256) ,SHA2('SamplePass_WithAddedSalt',384) ,SHA2('SamplePass_WithAddedSalt',512) ); 

La taille de sortie de sha1 est de 160 bits. Ce qui est 160/8 == 20 caractères (si vous utilisez des caractères de 8 bits) ou 160/16 = 10 (si vous utilisez des caractères de 16 bits).

La longueur est donc comprise entre 10 caractères de 16 bits et 40 chiffres hexadécimaux.

Dans tous les cas, décidez du format que vous allez stocker et définissez le champ sur une taille fixe basée sur ce format. De cette façon, vous n’aurez aucun espace perdu.

Vous pouvez toujours vouloir utiliser VARCHAR dans les cas où vous ne stockez pas toujours un hachage pour l’utilisateur (c.-à-d. Authentifier les comptes / oublié l’URL de connexion). Une fois qu’un utilisateur a authentifié / modifié ses informations de connexion, il ne devrait plus pouvoir utiliser le hachage et ne devrait pas avoir de raison de le faire. Vous pouvez créer une table distincte pour stocker les associations de hachage temporaires -> utilisateur qui pourraient être supprimées, mais je ne pense pas que la plupart des gens prennent la peine de le faire.

Si vous avez besoin d’un index sur la colonne sha1, je suggère CHAR (40) pour des raisons de performances. Dans mon cas, la colonne sha1 est un jeton de confirmation de courrier électronique. Par conséquent, sur la page de destination, la requête n’entre qu’avec le jeton. Dans ce cas, CHAR (40) avec INDEX, à mon avis, est le meilleur choix 🙂

Si vous souhaitez adopter cette méthode, n’oubliez pas de laisser $ raw_output = false.