web-dev-qa-db-fra.com

Meilleures pratiques: saler et poivrer les mots de passe?

Je suis tombé sur une discussion au cours de laquelle j'ai appris que ce que je faisais ne consistait pas à saler les mots de passe, mais à les émailler, et j'ai depuis commencé à faire les deux avec une fonction comme:

hash_function($salt.hash_function($pepper.$password)) [multiple iterations]

En ignorant l'algorithme de hachage choisi (je veux que ce soit une discussion sur les sels et les poivrons et non sur des algorithmes spécifiques mais j'utilise un algorithme sécurisé), s'agit-il d'une option sécurisée ou devrais-je faire quelque chose de différent? Pour ceux qui ne connaissent pas les termes:

  • A salt est une valeur générée aléatoirement, généralement stockée avec la chaîne dans la base de données, conçue pour rendre impossible l'utilisation de tables de hachage pour déchiffrer les mots de passe. Comme chaque mot de passe a son propre sel, il faut les forcer individuellement pour les déchiffrer. Toutefois, comme le sel est stocké dans la base de données avec le hachage du mot de passe, une compromission de la base de données signifie la perte des deux.

  • A poivre est une valeur statique à l'échelle du site, stockée séparément de la base de données (généralement codée en dur dans le code source de l'application) et destinée à être secrète. Il est utilisé de manière à ce que la base de données ne soit pas compromise si la table de mots de passe de l'ensemble de l'application n'est pas brutale.

Y a-t-il quelque chose qui me manque et le fait de saler et poivrer mes mots de passe est-il la meilleure option pour protéger la sécurité de mes utilisateurs? Y at-il une faille de sécurité potentielle à le faire de cette façon?

Remarque: Supposons que, pour les besoins de la discussion, l'application et la base de données soient stockées sur des ordinateurs distincts, ne partagez pas les mots de passe, etc., de sorte qu'une violation du serveur de base de données ne signifie pas automatiquement une violation serveur d'application.

137
Glitch Desire

D'accord. Vu que j'ai besoin d'écrire à ce sujet fin et fin , je vais faire une dernière réponse canonique sur le poivre seul.

L'aspect apparent des poivrons

Il semble bien évident que les poivrons devraient rendre les fonctions de hachage plus sûres. Je veux dire, si l'attaquant ne récupère que votre base de données, les mots de passe de vos utilisateurs doivent être sécurisés, n'est-ce pas? Cela semble logique, non?

C'est pourquoi tant de gens croient que les poivrons sont une bonne idée. Ca a du sens".

La réalité des poivrons

Dans les domaines de la sécurité et de la cryptographie, "donner un sens" ne suffit pas. Quelque chose doit être prouvable et ont un sens pour qu'il soit considéré comme sécurisé. De plus, il doit être implémentable de manière maintenable. Le système le plus sécurisé qui ne peut pas être maintenu est considéré comme non sécurisé (car si une partie de cette sécurité tombe en panne, tout le système tombe en morceaux).

Et les poivrons ne correspondent ni aux modèles prouvables ni aux modèles maintenables ...

Problèmes théoriques avec les poivrons

Maintenant que nous avons préparé le terrain, examinons ce qui ne va pas avec les poivrons.

  • Nourrir un hachage dans un autre peut être dangereux.

    Dans votre exemple, vous faites hash_function($salt . hash_function($pepper . $password)).

    Nous savons par expérience que "nourrir" simplement un résultat de hachage dans une autre fonction de hachage peut réduire la sécurité globale. La raison en est que les deux fonctions de hachage peuvent devenir une cible d'attaque.

    C'est pourquoi des algorithmes tels que PBKDF2 utilisent des opérations spéciales pour les combiner (hmac dans ce cas).

    Le fait est que bien que ce ne soit pas un gros problème, ce n’est pas non plus une chose banale que de simplement jeter autour. Les systèmes de cryptographie sont conçus pour éviter les cas "devrait fonctionner" et se concentrer sur les cas "conçus pour fonctionner".

    Bien que cela puisse sembler purement théorique, ce n’est en fait pas le cas. Par exemple, Bcrypt ne peut pas accepter de mots de passe arbitraires . Donc, passer bcrypt(hash(pw), salt) peut effectivement donner un hachage beaucoup plus faible que bcrypt(pw, salt) si hash() renvoie une chaîne binaire.

  • Travailler contre le design

    La manière dont bcrypt (et d'autres algorithmes de hachage de mot de passe) ont été conçus consiste à fonctionner avec un sel. Le concept d'un poivron n'a jamais été introduit. Cela peut sembler une trivialité, mais ce n’est pas le cas. La raison est qu'un sel n'est pas un secret. C'est juste une valeur qui peut être connue d'un attaquant. Un poivron, par définition, est par définition un secret cryptographique.

    Les algorithmes de hachage de mot de passe actuels (bcrypt, pbkdf2, etc.) sont tous conçus pour ne prendre qu'une seule valeur secrète (le mot de passe). L'ajout d'un autre secret dans l'algorithme n'a pas du tout été étudié.

    Cela ne signifie pas que ce n'est pas sûr. Cela signifie que nous ne savons pas si c'est sécuritaire. Et la recommandation générale avec la sécurité et la cryptographie est que si nous ne le savons pas, ce n’est pas le cas.

    Ainsi, tant que les cryptographes ne conçoivent pas et ne vérifient pas les algorithmes à utiliser avec des valeurs secrètes (poivrons), ils ne doivent pas utiliser les algorithmes actuels.

  • La complexité est l'ennemi de la sécurité

    Croyez-le ou non, La complexité est l'ennemi de la sécurité . Rendre un algorithme qui a l'air complexe peut être sécurisé ou non. Mais les chances sont assez importantes que ce ne soit pas sécurisé.

Problèmes importants avec les poivrons

  • Ce n'est pas maintenable

    Votre implémentation de poivrons empêche la possibilité de faire pivoter la clé poivron. Comme le poivron est utilisé à l'entrée de la fonction unidirectionnelle, vous ne pouvez jamais le changer pour la durée de vie de la valeur. Cela signifie que vous auriez besoin de trouver quelques astuces géniales pour qu'il prenne en charge la rotation des clés.

    Ceci est extrêmement important , car il est indispensable lorsque vous stockez des secrets cryptographiques. Ne pas avoir de mécanisme de rotation des clés (périodiquement et après une violation) est une vulnérabilité de sécurité énorme.

    Et votre approche actuelle en matière de poivron exigerait que chaque utilisateur ait son mot de passe complètement invalidé par une rotation ou attende la prochaine connexion pour effectuer la rotation (ce qui peut ne jamais être le cas) ...

    Ce qui rend fondamentalement votre approche immédiate sans issue.

  • Il vous faut rouler votre propre crypto

    Comme aucun algorithme actuel ne prend en charge le concept de poivre, vous devez donc composer des algorithmes ou en inventer de nouveaux pour prendre en charge un poivre. Et si vous ne voyez pas immédiatement pourquoi c'est une très mauvaise chose:

    N'importe qui, de l'amateur le plus désemparé au meilleur cryptographe, peut créer un algorithme qu'il ne peut pas détruire lui-même.

    [~ # ~] jamais [~ # ~] lancez votre propre crypto ...

La meilleure façon

Donc, parmi tous les problèmes détaillés ci-dessus, il y a deux façons de gérer la situation.

  • Il suffit d'utiliser les algorithmes tels qu'ils existent

    Si vous utilisez correctement bcrypt ou scrypt (avec un coût élevé), tous les mots de passe de dictionnaire, sauf les plus faibles, doivent être statistiquement sûrs. L’enregistrement actuel pour le hachage de bcrypt au coût 5 est de 71 000 hachages par seconde. À ce rythme, même un mot de passe aléatoire de 6 caractères prendrait des années à craquer. Et compte tenu de mon coût minimum recommandé de 10, cela réduit les hachages par seconde d'un facteur 32. Donc, nous ne parlerions que d'environ 2200 hachages par seconde. À ce rythme, même certaines phrases ou modifications du dictionnaire peuvent être protégées.

    De plus, nous devrions vérifier l'absence de ces classes de mots de passe faibles à la porte et ne pas les laisser entrer. À mesure que la fissuration des mots de passe devient plus avancée, les exigences de qualité du mot de passe le devraient également. C'est toujours un jeu statistique, mais avec une technique de stockage appropriée et des mots de passe forts, tout le monde devrait être pratiquement très sûr ...

  • Crypter le hachage de sortie avant le stockage

    Il existe dans le domaine de la sécurité un algorithme conçu pour gérer tout ce que nous avons dit plus haut. C'est un chiffrement en bloc. C'est bien, parce que c'est réversible, donc on peut faire tourner les clés (yay! Maintenabilité!). C'est bien parce que c'est utilisé comme prévu. C'est bien parce que cela ne donne aucune information à l'utilisateur.

    Regardons à nouveau cette ligne. Supposons qu'un attaquant connaisse votre algorithme (ce qui est nécessaire pour la sécurité, sinon c'est la sécurité par l'obscurité). Avec une approche traditionnelle au poivre, l’attaquant peut créer un mot de passe sentinelle et, puisqu'il connaît le sel et la sortie, il peut forcer le poivre brutalement. Ok, c'est long, mais c'est possible. Avec un chiffre, l'attaquant ne reçoit rien. Et comme le sel est aléatoire, un mot de passe sentinel ne l’aidera même pas. Donc, le mieux est qu'il leur reste à attaquer la forme cryptée. Ce qui signifie qu'ils doivent d'abord attaquer votre hachage chiffré pour récupérer la clé de chiffrement, puis attaquer les hachages. Mais il y a beaucoup de recherches sur l'attaque des chiffreurs, nous voulons donc nous en remettre à cela.

TL/DR

N'utilisez pas de poivrons. Il existe une foule de problèmes avec eux, et il y a deux meilleures façons: ne pas utiliser de secret côté serveur (oui, c'est bon) et chiffrer le hachage de sortie en utilisant un chiffrement par bloc avant le stockage.

295
ircmaxell

Fist nous devrions parler de la avantage exact d'un poivron:

  • Le pepper peut protéger les mots de passe faibles d'une attaque par dictionnaire, dans le cas spécial où l'attaquant a un accès en lecture à la base de données (contenant les hachages) mais n'a pas accès au code source avec pepper.

Un scénario typique serait l'injection SQL, les sauvegardes jetées, les serveurs mis au rebut ... Ces situations ne sont pas aussi rares qu'il y paraît, et souvent sous votre contrôle (hébergement de serveur). Si tu utilises...

  • Un sel unique par mot de passe
  • Un algorithme de hachage lent comme BCrypt

... les mots de passe forts sont bien protégés. Il est presque impossible de forcer brutalement un mot de passe fort dans ces conditions, même lorsque le sel est connu. Le problème concerne les mots de passe faibles, qui font partie d'un dictionnaire de force brute ou qui en sont dérivés. Une attaque par dictionnaire révélera ces informations très rapidement, car vous ne testez que les mots de passe les plus courants.

La deuxième question est comment appliquer le poivre?

Une méthode souvent recommandée pour appliquer un poivron consiste à combiner le mot de passe et le poivron avant de le transmettre à la fonction de hachage:

$pepperedPassword = hash_hmac('sha512', $password, $pepper);
$passwordHash = bcrypt($pepperedPassword);

Cependant, il existe un autre moyen encore meilleur:

$passwordHash = bcrypt($password);
$encryptedHash = encrypt($passwordHash, $serverSideKey);

Cela permet non seulement d'ajouter un secret côté serveur, mais aussi d'échanger le $ serverSideKey, si cela est nécessaire. Cette méthode nécessite un peu plus de travail, mais si le code existe déjà (bibliothèque), il n'y a aucune raison de ne pas l'utiliser.

23
martinstoeckli

Le sel et le poivre ont pour objectif d'augmenter le coût d'une recherche de mot de passe pré-calculée, appelée table Rainbow.

En général, il est difficile de trouver une collision pour un hachage unique (en supposant que le hachage est sécurisé). Cependant, avec des hachages courts, il est possible d’utiliser un ordinateur pour générer tous les hachages possibles dans une recherche sur un disque dur. Ceci s'appelle une table d'arc-en-ciel. Si vous créez une table Rainbow, vous pouvez alors aller dans le monde et trouver rapidement des mots de passe plausibles pour tout hachage (non salé, non trié).

Le but d'un piment est de rendre unique la table Rainbow nécessaire pour pirater votre liste de mots de passe. Donc, perdre plus de temps sur l'attaquant pour construire la table Rainbow.

Le sel est toutefois de faire en sorte que la table Rainbow de chaque utilisateur soit unique pour l'utilisateur, ce qui accroît encore la complexité de l'attaque.

En réalité, l’intérêt de la sécurité informatique n’est presque jamais de rendre cela (mathématiquement) impossible, mais mathématiquement et physiquement irréalisable (par exemple, dans des systèmes sécurisés, il faudrait toute l’entropie de l’univers (et plus encore) pour calculer le mot de passe d’un seul utilisateur).

2
Aron

Impossible de voir le stockage d’une valeur codée en dur dans votre code source comme présentant un intérêt pour la sécurité. C'est la sécurité à travers l'obscurité.

Si un pirate informatique acquiert votre base de données, il pourra commencer à forcer brutalement vos mots de passe utilisateur. Ce pirate informatique ne mettra pas longtemps à identifier votre poivre s’il parvient à déchiffrer quelques mots de passe.

1
Sven