web-dev-qa-db-fra.com

Comment stocker de manière sécurisée le mot de passe et le sel d'un utilisateur dans MySQL?

J'ai donc découvert sur SO que vous êtes censé hacher le mot de passe avec un "sel". (Les articles peuvent être trouvés ici et ici .)

Voici le code:

$password = 'fish';

/* should be "unique" for every user? */
$salt= 'ABC09';

$site_key = 'static_site_key';

hash_hmac('sha1', $password . $salt, $site_key);

Et maintenant, je dois sauvegarder à la fois le $password et le $salt dans MySQL, comme suit:

+---------+--------+----------+-------+
| user_id |  name  | password |  salt |
+---------+--------+----------+-------+
|    1    | krysis |  fish**  | ABC09 |
+---------+--------+----------+-------+

** fish sera bien sûr haché et non stocké en texte brut.

Et je me demande simplement s'il est logique de le faire de cette façon, parce que de cette façon un pirate informatique ou quiconque connaîtra également le sel? Ainsi, s’ils déchiffrent le mot de passe et qu’ils voient que c’est fishABC09, ils sauront automatiquement que le mot de passe est fish? Ou pourrait-il "jamais" être capable de déchiffrer le mot de passe car il ne connaît pas le secret_key, car il n'est pas stocké dans la base de données?

Je suis désolé si je ne fais pas de sens. Je viens de toujours utiliser sha1 pour les mots de passe, et aujourd'hui j'ai trouvé ces articles qui parlaient de l'ajout d'une salt.

16
user317005

Il existe de bons articles sur le stockage correct des mots de passe. L'un d'eux, par exemple: Stockage des mots de passe - bien fait!

Vous devriez utiliser un sel différent pour chaque utilisateur, mais il n'est pas nécessaire de stocker les sels séparément. Voir la discussion similaire dans un autre fil

En passant, vous ne devriez probablement pas utiliser sha1 mais par exemple. sha256 ou sha512 quelque chose de plus fort à la place (au moins pour éviter une mauvaise publicité). Il existe une bonne réponse à ce sujet: Quelle insécurité est un SHA1 salé par rapport à un SHA512 salé

8
kto

Rainbow/Dictionary Attacks et les mots de passe salés - une approche hérétique

Les mots de passe ne doivent pas être stockés dans votre base de données. Ne lancez pas votre propre mécanisme d'authentification - vous vous y tromperez certainement. Utilisez Kereberos pour des choses de valeur, et bien je n’aurais pas une bonne suggestion sinon.

Cependant, cette question me trotte dans la tête depuis un moment (voir les modifications) Et je voudrais mettre un point de vue hérétique dessus.

Les tables arc-en-ciel sont appelées ainsi à cause de la manière dont le mécanisme de recherche (chaînage) est utilisé - mais ce ne sont que des attaques par dictionnaire. Des millions de mots du dictionnaire et de mots de passe communs sont hachés à l’avant puis utilisés pour comparer les mots de passe hachés volés.

Cela a bien fonctionné pour le processus de mot de passe NT4 qui utilisait des hachages md5 sans sel. Mais Quand un sel est ajouté à un mot de passe avant le hachage, la table Rainbow est inutile - au lieu de rechercher le hachage md5 de "mypass", il doit précalculer "mypass-random-string_of-letters"

Il est impossible de deviner le type de sel que quelqu'un utilisera. Le salage rend donc les tables Rainbow génériques, utilisables n'importe où contre n'importe quelle solution de serveur morte dans l'eau.

mais ...

Ce n’est qu’un seul cas d’utilisation - certainement une grande menace, certainement un défi à défendre. Mais A un problème. Vous devez conserver le sel pendant la prochaine authentification de l'utilisateur. Ils envoient leur texte en clair (sur ssl!), Vous ajoutez le sel et le hachage, ainsi que le hachage stocké dans la base de données. Mais si vous ne gardez pas le sel avec le mot de passe, vous ne pouvez pas le faire, et errr ... no login

Mais nous ne nous défendons pas uniquement contre les gens qui passent autour d’une table pour craquer les mots de passe NT4. Nous sommes censés protéger nos utilisateurs individuellement.

Un sel ajoute une défense à deux facteurs aux mots de passe - même avec le hachage, un attaquant aura besoin du sel pour avoir la moindre chance de le déchiffrer. Mais le conseil standard ne fait qu'abandonner cette défense à deux facteurs. C'est probablement raisonnable, mais je ne suis pas convaincu.

Il y a un peu de maths derrière cela. Le conseil habituel (également fourni par RSA - ftp.rsa.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf) est de construire un sel 64 bits, stockez-le avec le mot de passe haché . De cette façon, vous pouvez reconfirmer le mot de passe en répétant l'opération avec le sel et en inversant le hachage, ce qui est pratiquement impossible.

NB - Je peux me tromper ici ...

Le bit "à côté de l'impossible" vient de simples maths. 

Supposons un mot de passe à 8 chiffres, avec 62 caractères possibles (lettres, majuscules et chiffres)

C’est 62 ^ 8 combinaisons, soit un peu plus de 200 millions de milliards de dollars.

Pour le forcer brutalement, en calculant le hachage directement (c’est-à-dire en fabriquant mes tables Rainbow spécifiques au sel), je devrais assister à une collision après 62 ^ 8/2 et, disons, à 100 hachages par seconde, cela prendra environ 12 millions de jours. Oui jours.

OK, donc même stocker le hachage avec le mot de passe rend la tâche de trouver le hachage assez difficile à réaliser.

Cependant, il existe certaines hypothèses dans ce qui précède. Premièrement, le mot de passe est un choix aléatoire de la plage 62 ^ 8. En pratique, la plupart des mots de passe sont beaucoup plus faibles - les tables Rainbow ne sont pas basées sur toutes les possibilités - mais elles sont construites à partir de dictionnaires et de véritables tables de mots de passe trouvées au fil des ans.

Ainsi, l’espace de recherche, au lieu de 62 ^ 8, est vraiment plus petit. Petit comment? Le dépend du mot de passe "force". 

Il y a environ 250 000 à 750 000 mots en anglais (http://oxforddictionaries.com/page/93). Prenons 500 000 comme un cas simple. Prenons ensuite des variations qui peuvent être appliquées - ajouter un chiffre, ajouter une année, convertir les voyelles en chiffres. Cela nous donne 3 nouveaux mots possibles par mot, ou 2 millions de mots de passe possibles.

Générer 2 millions de hachages à 100/s donne 20 000 secondes ou 5 heures, ce qui est tout à fait à la portée de tout ordinateur portable. 

Donc, si un utilisateur spécifique est ciblé (root, admin, spolsky, etc.), le stockage d'un sel avec le mot de passe permet immédiatement la résolution du problème. 

Stocker le sel hors du mot de passe augmente la difficulté de la fissure - pas de manière mathématique, juste en difficulté pour obtenir le sel et le mot de passe. On pourrait envisager un serveur distinct prenant uniquement le texte en clair, le nom d'utilisateur et le hachage, et recherchant le sel Utilisé le jour de la jointure de l'utilisateur, et renvoyant 1/0

En bref, si vous stockez le sel avec le mot de passe et que quelqu'un accède aux mots de passe, alors, en fonction de la force du mot de passe, chaque mot de passe est fissurable dans un délai raisonnable. Un sel différent par utilisateur protège tous les autres utilisateurs, mais si vous recherchez un compte spécifique, cela n'a aucune pertinence. Si le pirate informatique ne cherche qu'un mot de passe, alors stocker un sel avec un mot de passe rend la fissure réalisable. Garder un sel en rotation ailleurs dans la table des mots de passe signifie que le pirate a maintenant besoin de deux vols de données pour déchiffrer le mot de passe, car sans ce sel, toute attaque est vouée à des milliers d'années de travail.

C’est un compromis: obliger les utilisateurs à utiliser des mots de passe à 15 chiffres signifie qu’ils obtiennent tous un message post-it affiché à l’écran ou deviennent "faciles à retenir", c’est-à-dire des mots.

À ce stade, vous pouvez également migrer vers Kerberos ou similaire - si les données que vous protégez sont précieuses, les utilisateurs les comprendront et les observeront. Si non pourquoi nous dérangeons.

Mais je vous recommande quand même de faire not mettre en place votre propre mécanique. Utilisez Kerberos, utilisez une PKI semi-publique, ne lancez pas le vôtre. Je ne sais pas comment dire si mon serveur a simplement échangé le RAM contenant mon sel sur un disque et ce n’est qu’une erreur à laquelle je peux immédiatement penser en faisant rouler ma propre authentification.

HTH

$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
$time = time();
$query = "
INSERT INTO user (name, unixcreationtime, passhash) 
VALUES ('$username', '$time', SHA2(CONCAT('$time','$password'),512) ";

N'utilisez pas SHA1, il n'est plus sécurisé.
Je suggère de faire tout le hachage dans MySQL, de cette façon, vous pouvez être sûr qu'il n'y a aucune différence dans le résultat du hachage. 

Sélectionnez un utilisateur en utilisant: 

$query = "SELECT id FROM user 
          WHERE name = '$username' 
            AND passhash = SHA2(CONCAT(creationdate,'$password'),512) ";
5
Johan

Non, car lorsque le mot de passe est haché, il ne ressemble pas à fishABC09, mais à: 5f4dcc3b5aa765d61d8327deb882cf99, qui est un hachage md5. 

Pour accéder à votre système, même s’ils connaissent le hachage, celui-ci ne peut pas être inversé. Nous utilisons des sels pour ajouter de la complexité à nos hachages et pour éviter les recherches de hachage dans les tables Rainbow.

Par exemple: Effectuez une recherche sur Google pour le hachage md5 de "mot de passe" qui est: 5f4dcc3b5aa765d61d8327deb882cf99 

Beaucoup de résultats, non?

Maintenant, je vais créer à nouveau un hachage, je vais toujours utiliser "mot de passe", mais je vais ajouter un SALT qui est "AHG (* @". Je suppose que la seule réponse sera pour ce message et quelques robots. qui ont lu ce post :)

cbe57e92ffbb0086320891b9f979156d

Devrait être seulement un quelques résultats , ou ce post qui sont ce post.

Rappelez-vous juste

Rappelez-vous simplement que ... les hash sont one way , donc même si vous obtenez le hash, vous ne savez pas ce qui a été utilisé pour le créer. 

4
Layke

Je sais que c'est vieux, mais pour quiconque parvient à trébucher sur ce post ...

Ce que vous essayez vraiment de faire, HMAC. Essayer de le faire vous-même crée des problèmes. Vous pouvez par exemple calculer partiellement les hachages, ce qui réduit par exemple les efforts nécessaires pour deviner un mot de passe. HMAC répond à ces préoccupations.

Mieux encore est scrypt ou bcrypt. HMAC utilise encore souvent des algorithmes de hachage conçus pour être simples et rapides à calculer. il existe même des implémentations matérielles de nombreux algorithmes de hachage. bcrypt est coûteux en calcul et consomme beaucoup de mémoire. Les deux rendent les choses plus difficiles pour un attaquant, mais le cryptage en particulier rend très difficile la création de périphériques matériels pour déchiffrer un mot de passe.

J'aime beaucoup le tableau ici: https://github.com/pbhogan/scrypt#why-you-should-use-scrypt

1
Sam Terrell

Si un pirate informatique accède à vos fichiers PHP, il peut simplement ajouter une fonction de courrier électronique. Ainsi, quels que soient les utilisateurs qui se connectent, les détails du compte sont envoyés par courrier électronique à l'intrus. 

Si un pirate informatique n’accède qu’à la base de données, il ne doit pas y écrire clairement les mots de passe. Cryptez-le avant de sauvegarder. Enregistrez-le dans le hachage md5 qui ne peut pas être inversé. 

J'utilise normalement sel en fonction du nom d'utilisateur ou de l'ID utilisateur, ce programme PHP sait comment générer pour chaque utilisateur avec static_site_key.

0
Atul Gupta

c’est un sujet ancien, mais d’autres viendront ici aussi, alors je vais essayer de le décrire très facilement:

si vous utilisez hash (mot de passe), vous obtenez la même valeur de hash pour chaque mot de passe [hash (mot de passe) = hash (mot de passe)]. Si deux utilisateurs ont le même mot de passe, vous le verrez car les valeurs de hachage sont les mêmes. Certains mots de passe, tels que "mot de passe" ou "12345678", sont utilisés très souvent de la sorte: même valeur de hachage dans votre base de données -> peut-être mot de passe "mot de passe" ou "12345678" (attaque par arc-en-ciel).

si vous utilisez un hachage (sel + mot de passe), vous n'obtenez pas le même hachage pour les mêmes mots de passe car le hachage (sel1 + mot de passe) n'est pas un hachage (sel2 + mot de passe).

hash (x) est juste une fonction mathématique comme f (x) = y. si vous mettez le même x, vous obtiendrez le même y. cette fonction doit être "spéciale" pour être sûre. il suffit de ne pas utiliser sha1 car ce n’est plus sûr: D

0
user2717345

Un sel est un nombre aléatoire d'une longueur fixe. Ce sel doit être différent pour chaque entrée stockée. Il doit être stocké sous forme de texte en clair à côté du mot de passe haché.

De

https://www.owasp.org/index.php/Hashing_Java#Why_add_salt_.3F