Quel type de données utiliser pour le champ de mot de passe haché et quelle longueur?

269

Je ne sais pas comment fonctionne le hachage de mot de passe (l'implémentera plus tard), mais je dois créer un schéma de base de données maintenant.

Je pense à limiter les mots de passe à 4-20 caractères, mais si je comprends bien, après le cryptage, la chaîne de hachage sera de longueur différente.

Alors, comment stocker ces mots de passe dans la base de données?

z-boss
la source
Voir également le framework de hachage de mot de passe PHP d'Openwall (PHPass). Son portable et renforcé contre un certain nombre d'attaques courantes contre les mots de passe des utilisateurs. Le gars qui a écrit le framework (SolarDesigner) est le même que celui qui a écrit John The Ripper et siège en tant que juge dans le concours de hachage de mot de passe . Il sait donc une chose ou deux sur les attaques de mots de passe.
2014
2
Veuillez ne pas imposer de limite supérieure à vos mots de passe. Vous les hachez, il n'y a aucune raison de stockage pour une limite supérieure. Si vous vous inquiétez des attaques DoS utilisant le hachage de mot de passe, 1000 ou 1024 est une limite supérieure raisonnable.
Iiridayn
pourquoi limiter la longueur du mot de passe? Laissez au moins un utilisateur créer un mot de passe de 100 caractères :)
Andrew
4 caractères est une borne inférieure assez dangereuse pour les mots de passe car ceux-ci sont triviaux à craquer. À tout le moins, utilisez 8, mais 14 ou 16, c'est beaucoup mieux.
quikchange
Il s'agit d'une très vieille question avec une réponse dépassée. Voir la réponse de Gilles pour la mise à jour.
kelalaka

Réponses:

448

Mise à jour: La simple utilisation d'une fonction de hachage n'est pas assez puissante pour stocker des mots de passe. Vous devriez lire la réponse de Gilles sur ce fil pour une explication plus détaillée.

Pour les mots de passe, utilisez un algorithme de hachage de renforcement des clés comme Bcrypt ou Argon2i. Par exemple, en PHP, utilisez la fonction password_hash () , qui utilise Bcrypt par défaut.

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

Le résultat est une chaîne de 60 caractères similaire à la suivante (mais les chiffres varient, car cela génère un sel unique).

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

Utilisez le type de données SQL CHAR(60)pour stocker cet encodage d'un hachage Bcrypt. Notez que cette fonction n'est pas codée comme une chaîne de chiffres hexadécimaux, nous ne pouvons donc pas la décompresser aussi facilement pour la stocker en binaire.

D'autres fonctions de hachage ont encore des utilisations, mais pas pour stocker des mots de passe, donc je garderai la réponse originale ci-dessous, écrite en 2008.


Cela dépend de l'algorithme de hachage que vous utilisez. Le hachage produit toujours un résultat de la même longueur, quelle que soit l'entrée. Il est typique de représenter le résultat de hachage binaire dans le texte, comme une série de chiffres hexadécimaux. Ou vous pouvez utiliser la UNHEX()fonction pour réduire de moitié une chaîne de chiffres hexadécimaux.

  • MD5 génère une valeur de hachage de 128 bits. Vous pouvez utiliser CHAR (32) ou BINARY (16)
  • SHA-1 génère une valeur de hachage de 160 bits. Vous pouvez utiliser CHAR (40) ou BINARY (20)
  • SHA-224 génère une valeur de hachage de 224 bits. Vous pouvez utiliser CHAR (56) ou BINARY (28)
  • SHA-256 génère une valeur de hachage de 256 bits. Vous pouvez utiliser CHAR (64) ou BINARY (32)
  • SHA-384 génère une valeur de hachage de 384 bits. Vous pouvez utiliser CHAR (96) ou BINARY (48)
  • SHA-512 génère une valeur de hachage de 512 bits. Vous pouvez utiliser CHAR (128) ou BINARY (64)
  • BCrypt génère une valeur de hachage de 448 bits dépendante de l'implémentation. Vous pourriez avoir besoin de CHAR (56), CHAR (60), CHAR (76), BINARY (56) ou BINARY (60)

Depuis 2015, le NIST recommande d'utiliser SHA-256 ou supérieur pour toutes les applications de fonctions de hachage nécessitant une interopérabilité. Mais le NIST ne recommande pas d'utiliser ces fonctions de hachage simples pour stocker les mots de passe en toute sécurité.

Les algorithmes de hachage moindres ont leurs utilisations (comme internes à une application, pas pour l'échange), mais ils sont connus pour être crackables .

Bill Karwin
la source
47
@Hippo: S'il vous plaît, n'utilisez pas le nom d'utilisateur comme sel. Générez un sel aléatoire par utilisateur.
Bill Karwin du
11
Oui, il n'y a aucune raison de ne pas le stocker dans la même rangée. Même si un attaquant accède à votre base de données, il devra construire sa table arc-en-ciel en fonction de ce sel. Et c'est tout autant de travail que de simplement deviner le mot de passe.
Bill Karwin
5
@SgtPooki: Vous avez besoin d'une autre colonne pour stocker le sel en texte brut. Ensuite, vous pouvez hacher le mot de passe de l'utilisateur avec le même sel lorsqu'il le saisit et comparer le résultat au condensé de hachage stocké dans la table.
Bill Karwin
12
Si vous stockez le sel dans la même table (ou tout autre emplacement avec les mêmes autorisations d'accès), il n'y a aucune raison de ne pas utiliser le nom d'utilisateur comme sel, car il sera unique par utilisateur. Cependant, tout sel connu rend le hachage cryptographiquement plus faible que s'il n'y avait pas de sel connu. Un sel n'ajoute de la valeur que s'il est également inconnu.
fijiaaron
9
Je ne comprends pas l'accord avec le sel connu ou inconnu. Si vous implémentez un site - le sel doit être connu de la page de connexion / du script / du service qui teste le mot de passe. Donc - vous défenseurs du sel "inconnus" - supposez-vous que le code du processus de connexion est inconnu de l'attaquant? Sinon - l'attaquant ne connaîtra-t-il pas toujours le sel, qu'il soit aléatoire, unique, stocké avec le mot de passe haché ou séparément?
mattstuehler
13

Vous pouvez réellement utiliser CHAR(longueur de hachage) pour définir votre type de données pour MySQL car chaque algorithme de hachage évaluera toujours le même nombre de caractères. Par exemple, SHA1renvoie toujours un nombre hexadécimal de 40 caractères.

Noah Goodrich
la source
1
SHA-1 n'est pas adapté au hachage de mots de passe.
Gilles 'SO- arrête d'être méchant'
10

Utilisez toujours un algorithme de hachage de mot de passe: Argon2 , scrypt , bcrypt ou PBKDF2 .

Argon2 a remporté le concours de hachage de mot de passe 2015. Scrypt , bcrypt et PBKDF2 sont des algorithmes plus anciens qui sont considérés comme moins préférés maintenant, mais toujours fondamentalement solides, donc si votre plate-forme ne prend pas encore en charge Argon2, il est acceptable d'utiliser un autre algorithme pour l'instant.

Ne stockez jamais un mot de passe directement dans une base de données. Ne le cryptez pas non plus: sinon, si votre site est piraté, l'attaquant obtient la clé de décryptage et peut donc obtenir tous les mots de passe. Les mots de passe DOIVENT être hachés .

Un hachage de mot de passe a des propriétés différentes d'un hachage de table de hachage ou d'un hachage cryptographique. N'utilisez jamais un hachage cryptographique ordinaire tel que MD5, SHA-256 ou SHA-512 sur un mot de passe. Un algorithme de hachage de mot de passe utilise un sel , qui est unique (non utilisé pour un autre utilisateur ou dans la base de données de quelqu'un d'autre). Le sel est nécessaire pour que les attaquants ne puissent pas simplement pré-calculer les hachages des mots de passe courants: avec un sel, ils doivent recommencer le calcul pour chaque compte. Un algorithme de hachage de mot de passe est intrinsèquement lent - aussi lent que possible. La lenteur blesse beaucoup plus l'attaquant que vous car l'attaquant doit essayer de nombreux mots de passe différents. Pour plus d'informations, consultez Comment hacher en toute sécurité les mots de passe .

Un hachage de mot de passe code quatre informations:

  • Un indicateur de l'algorithme utilisé. Cela est nécessaire pour l' agilité : les recommandations cryptographiques changent avec le temps. Vous devez pouvoir passer à un nouvel algorithme.
  • Un indicateur de difficulté ou de dureté. Plus cette valeur est élevée, plus le calcul est nécessaire pour calculer le hachage. Cela devrait être une valeur de configuration constante ou globale dans la fonction de changement de mot de passe, mais elle devrait augmenter avec le temps à mesure que les ordinateurs s'accélèrent, vous devez donc vous souvenir de la valeur de chaque compte. Certains algorithmes ont une seule valeur numérique, d'autres y ont plus de paramètres (par exemple pour régler séparément l'utilisation du CPU et l'utilisation de la RAM).
  • Le sel. Étant donné que le sel doit être unique au monde, il doit être stocké pour chaque compte. Le sel doit être généré de manière aléatoire à chaque changement de mot de passe.
  • Le hachage proprement dit, c'est-à-dire la sortie du calcul mathématique dans l'algorithme de hachage.

De nombreuses bibliothèques incluent une fonction de paire qui regroupe commodément ces informations en une seule chaîne: une qui prend l'indicateur d'algorithme, l'indicateur de dureté et le mot de passe, génère un sel aléatoire et renvoie la chaîne de hachage complète; et celui qui prend un mot de passe et la chaîne de hachage complète comme entrée et renvoie un booléen indiquant si le mot de passe était correct. Il n'y a pas de norme universelle, mais un codage commun est

$ algorithme $ paramètres $ sel $ sortie

algorithmest un nombre ou une chaîne alphanumérique courte codant le choix de l'algorithme, parametersest une chaîne imprimable et saltet outputsont codés en Base64 sans se terminer =.

16 octets suffisent pour le sel et la sortie. (Voir par exemple les recommandations pour Argon2 .) Encodé en Base64, c'est 21 caractères chacun. Les deux autres parties dépendent de l'algorithme et des paramètres, mais 20 à 40 caractères sont typiques. Cela représente un total d' environ 82 caractères ASCII ( CHAR(82), et pas besoin d'Unicode), auxquels vous devez ajouter une marge de sécurité si vous pensez qu'il sera difficile d'agrandir le champ plus tard.

Si vous codez le hachage dans un format binaire, vous pouvez le réduire à 1 octet pour l'algorithme, 1 à 4 octets pour la dureté (si vous codez en dur certains des paramètres) et 16 octets chacun pour le sel et la sortie , pour un total de 37 octets. Disons 40 octets ( BINARY(40)) pour avoir au moins deux octets de rechange. Notez qu'il s'agit d'octets 8 bits, pas de caractères imprimables, en particulier le champ peut inclure des octets nuls.

Notez que la longueur du hachage est complètement indépendante de la longueur du mot de passe.

Gilles 'SO- arrête d'être méchant'
la source
9

Vous trouverez peut-être utile cet article Wikipedia sur le salage . L'idée est d'ajouter un ensemble de données pour randomiser votre valeur de hachage; cela protégera vos mots de passe des attaques par dictionnaire si quelqu'un obtient un accès non autorisé aux hachages de mot de passe.

Dana la saine
la source
2
Cela vaut vraiment la peine (+1), mais cela ne répond pas à la question! (-1)
Bill Karwin
3
Oui, mais certainement pertinent dans ce contexte (+1)
Treb
7

En tant que chaîne de longueur fixe (VARCHAR (n) ou comme MySQL l'appelle). Un hachage a toujours une longueur fixe, par exemple de 12 caractères (selon l'algorithme de hachage que vous utilisez). Ainsi, un mot de passe de 20 caractères serait réduit à un hachage de 12 caractères, et un mot de passe de 4 caractères donnerait également un hachage de 12 caractères.

Treb
la source
3
'ou comme MySQL l'appelle' - MYSQL l'appelle CHAR. Ce type est pour une valeur de longueur fixe. Je pense donc que CHAR est meilleur type que VARCHAR.
t298712383
4

Vous devez utiliser TEXT(stocker un nombre illimité de caractères) pour des raisons de compatibilité ascendante. Les algorithmes de hachage (doivent) devenir plus forts au fil du temps et donc ce champ de base de données devra prendre en charge plus de caractères au fil du temps. De plus, selon votre stratégie de migration, vous devrez peut-être stocker des hachages nouveaux et anciens dans le même champ, il n'est donc pas recommandé de fixer la longueur à un type de hachage.

Bart
la source
3

Cela dépend vraiment de l'algorithme de hachage que vous utilisez. La longueur du mot de passe a peu à voir avec la longueur du hachage, si je me souviens bien. Recherchez les spécifications de l'algorithme de hachage que vous utilisez, exécutez quelques tests et tronquez juste au-dessus.

dira
la source
3

Les hachages sont une séquence de bits (128 bits, 160 bits, 256 bits, etc., selon l'algorithme). Votre colonne doit être de type binaire, et non de type texte / caractère, si MySQL le permet (le type de données SQL Server est binary(n)ou varbinary(n)). Vous devez également saler les hachis. Les sels peuvent être textuels ou binaires, et vous aurez besoin d'une colonne correspondante.

yfeldblum
la source
La justice est tout à fait correcte ici - MySQL les stockera sous forme de valeurs numériques et rendra la recherche sur cette colonne beaucoup plus efficace que de faire une correspondance de chaîne, mais les sels ne doivent pas être stockés dans la base de données à côté des données salées - ce qui élimine la sécurité que les sels offrent .
Tony Maro
6
Les sels ne sont pas secrets. Le seul secret est le mot de passe. Assurez-vous simplement que chaque nouveau mot de passe reçoit un nouveau sel. Chaque fois que l'utilisateur change son mot de passe, le système doit générer un nouveau sel pour ce mot de passe. Les sels doivent être longs et aléatoires, tels que 16 octets générés à partir d'un PRNG cryptographiquement sécurisé.
yfeldblum
1
@TonyMaro Je ne sais pas si une correspondance de chaîne de mot de passe au niveau SQL est une bonne stratégie. En d'autres termes, vous ne devez pas rechercher un mot de passe dans votre base de données, mais récupérer l'utilisateur en fonction de son nom d'utilisateur et comparer les mots de passe en code plutôt qu'en SQL.
bart
1

J'ai toujours testé pour trouver la longueur de chaîne MAX d'une chaîne chiffrée et la définir comme la longueur de caractère d'un type VARCHAR. Selon le nombre d'enregistrements que vous allez avoir, cela pourrait vraiment aider à la taille de la base de données.

Stephen Walcher
la source
0

pour md5 vARCHAR (32) est approprié. Pour ceux qui utilisent AES, il vaut mieux utiliser varbinary.

Hare Srinivasa
la source
1
Ni MD5 ni AES ne conviennent pour hacher un mot de passe.
Gilles 'SO- arrête d'être méchant'