La meilleure fonction pour hasher les mot de passe

PHP

Le problème exposé dans ce sujet a été résolu.

D'un point de vue théorique, il y a essentiellement 3 moyens d'attaquer un/plusieurs mots de passe hashés.

La première est de "casser" la fonction de hash elle-même. En prenant une bonne fonction de hash (genre sha512 ou whirlpool), tu peux raisonnablement ignorer ce vecteur d'attaque puisqu'il sera bien plus simple pour un attaquant de trouver et exploiter une faille ailleurs dans ton système.

Deuxièmement, tu as les rainbow tables. L'idée étant de prémâcher la tâche de brute-force : tu te retrouves avec la possibilité d'inverser ta fonction de hash pour un nombre conséquent de sortie possible. Avec un sel dynamique (chaque utilisateur à un sel différent) aléatoire et assez grand, une attaque par rainbow table ne donnera probablement rien. À noter qu'avec un sel statique (le même pour tout le monde), il est toujours possible de générer une rainbow table pour tous tes utilisateurs, ce qui peux être rentable suivant le nombre d'utilisateur.

Finalement, tu as le risque d'attaque par brute force ou dictionnaire. Mettons que 10% de tes utilisateurs ont eu la brillante idée de choisir un mot de passe parmi les 1000 mots de passes les plus courants. Il faudra alors en moyenne 100010temps de hash à ton attaquant pour trouver un mot de passe en moyenne. Si tu veux gêner ton attaquant, la solution la plus simple est d'augmenter le temps de hash. L'idée est souvent d'appliquer ta fonction de hash x fois, ce qui multiplie par x ton temps de hash. Par contre, c'est une mauvaise idée de faire ça aussi simplement parce que ça réduit potentiellement la sécurité de ta fonction de hash. En revanche password_hash a une option pour gérer le coût de hash. À toi de voir combien tu veux dépenser de puissance de calcul pour protéger tes utilisateurs contre des attaques par brute force ou dictionnaire.

Les fonctions de hashage du type SHA-256 ne sont pas adaptés pour hasher les mots de passe. Ils sont seulement utiles pour faire des contrôles d’intégrité sur des fichiers qui pourraient être corrompus de manière accidentelles (mais pas si on veut se protéger pour des modifications malveillantes).

Par contre la fonction password_hash() est tout à fait adapté à ton problème, puisqu’elle utilise l’algorithme bcrypt, qui a été spécifiquement conçu pour cela. Il est important d’utiliser la fonction password_verify() pour comparer l’empreinte générée par la saisie de l’utilisateur et l’empreinte stockée, et surtout pas l’opérateur == de PHP.

Si tu veux plus de détails et que l’anglais ne t’effraie pas, voici un lien très instructif sur cette question :

https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016

Et je conseille par ailleurs de lire le premier lien qui est donné dans l’article pour faire le point sur le vocabulaire.

Notez bien que je ne suis absolument pas expert en sécurité.

+0 -0

Il est aussi conseillé de mettre l'id ou le nom d'utilisateur avec le mot de passe, pour éviter d'identifier les mots de passe identique (et donc faible).

A-312

Avec password_hash ? Quelles sont les chances de générer le même salage pour deux mots de passe identiques ? En plus ça ne changera rien à du brute force …

+0 -0

Il est aussi conseillé de mettre l'id ou le nom d'utilisateur avec le mot de passe, pour éviter d'identifier les mots de passe identique (et donc faible).

A-312

Avec password_hash ? Quelles sont les chances de générer le même salage pour deux mots de passe identiques ? En plus ça ne changera rien à du brute force …

vibrice

A priori, si on précise pas l'algo à utiliser et qu'on précise pas de salt, password_hash devrait générer l'exact même salt environ 1 fois sur 2^176. C'est à dire une chance sur 95780971304118053647396689196894323976171195136475136.

[edit] En fait pour répondre à cette question de vibrice j'ai juste rapidement jeté un oeil au code de PHP. Mais j'ai regardé un peu trop vite. 22 c'est pas le nombre de bytes d'entropie du salt, 22 c'est le nombre de caractères en base64 pour encoder le salt. L'entropie c'est 22*3/4+1, soit 16.5 -> 17 bytes. Donc 1/2^17 chances d'en avoir 2 mêmes.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte