Sauvegarder les mots de passe dans Postgresql avec bcrypt
On voit de plus en plus souvent dans les news, que des bases de données se sont faites hackées, et des gros dumps de mots de passe circulent ainsi dans la nature.
La sauvegarde old school
La manière classique de sauvegarder les mots de passe utilisateur est de les garder en clair de les hasher (md5, sha1, …) avec un salt.
Exemple:
md5(salt + mdp) md5("AvecCettePhraseAleatoirePersonneNeTrouveraLesMDP" + "MonMotDePasseDeLaMortQuiTue") = 3576e3ae9dc9263a09fc321710f8224f
Voila, on récupère ainsi une chaine de caractère illisible. Le problème c’est qu’elle est crackable très très rapidement, puisque les algorithmes de hash rapides, tels que md5 et ceux de la famille SHA, ne sont plus vraiment fiables: voir cet article.
Et oui décrypter un hash en quelques secondes avec les technologies d’aujourd’hui est clairement possible.
La nouvelle façon
Maintenant il existe une approche plus moderne pour faire tout ça avec Postgresql: bcrypt qui fait partie du module pgcrypto.
Attention, si vous avez déjà une application avec des utilisateurs, ils seront obligés de mettre à jour leur mot de passe pour cette nouvelle solution.
Avantages de bcrypt
- On utilise un algorithme de hash lent (Blowfish)
- Plusieurs cycles de hash sont exécutés afin de renforcer la sécurité
- Un salt aléatoire est généré pour chaque mot de passe. Inutile de garder un salt dans son code/BDD et la sécurité est plus accrue.
Mise en place
Modification du type du champ mot de passe (facultatif):
ALTER TABLE utilisateur ALTER COLUMN password TYPE VARCHAR(60);
Ajout du module à votre base:
CREATE EXTENSION pgcrypto;
Mise à jour d’un mot de passe pour un utilisateur donné:
UPDATE utilisateur SET password = crypt('MonMotDePasse', gen_salt('bf',8)) WHERE id = 59;
Dans la génération du salt, bf correspond à l’algorithme (blowfish) et le chiffre 8 correspond au nombre de passage. Plus le nombre de passage est élevé, plus c’est long et plus c’est sécurisé. Sur la doc de pgcrypto il est conseillé d’avoir une vitesse d’exécution entre 4 et 100 mots de passe par seconde. La vitesse change évidemment suivant la puissance du processeur. Un tableau est aussi disponible, toujours sur la doc afin de comparer les temps d’exécution suivant les différents types d’algorithme avec un même processeur.
Comparer le mot de passe entré par l’utilisateur à celui en base:
SELECT * FROM utilisateur WHERE password = crypt('MonMotDePasse', password);
Ici le mot de passe en base est utilisé comme salt du mot de passe entré.
Et voila, il n’y a rien de bien compliqué, c’est facile à mettre en place, donc sautez sur l’occasion pour améliorer la sécurité de votre application.