web-dev-qa-db-fra.com

Comment appliquer correctement un poivre sur bcrypt?

Mise à jour: il existe un meilleur moyen d'ajouter une clé côté serveur que de l'utiliser comme poivre. Avec un poivre, un attaquant doit obtenir des privilèges supplémentaires sur le serveur pour obtenir la clé. Le même avantage que nous obtenons en calculant d'abord le hachage, puis en chiffrant le hachage avec la clé côté serveur (cryptage bidirectionnel). Cela nous donne la possibilité d'échanger la clé chaque fois que cela est nécessaire.

Pour hacher des mots de passe dans une base de données, je voudrais ajouter un poivre à la fonction de hachage. Bien sûr, ce poivre sera en plus du sel unique.

La raison pour laquelle je veux ajouter un piment est qu'il empêche une attaque par dictionnaire, au cas où l'attaquant n'aurait accès qu'à la base de données, mais pas au serveur (typique pour Sql-Injection). À mon avis, c'est mieux qu'un hachage sans poivre, même si le poivre est uniquement codé en dur (pour éviter la complexité du code).

Maintenant, je me demande comment appliquer le piment correctement. Est-il correct de simplement ajouter le piment au mot de passe avant de hacher?

1. Concaténation du mot de passe et du poivre

$passwordHash = bcrypt($password . $pepper, $salt);

Une raison à cela pourrait être que les mots de passe plus grands que la limite bcrypt (55 caractères) n'obtiendront pas le poivre, bien que les mots de passe de cette longueur ne soient de toute façon pas dans un dictionnaire. En raison de cette limite, le piment est ajouté après le mot de passe et pas avant. Une autre raison pourrait être que si l'attaquant connaît le poivre, il connaît également la fin de tous nos mots de passe poivrés.

2. Combinez le mot de passe et le poivre avec du hachage

$passwordHash = bcrypt(hash('sha256', $password . $pepper), $salt);

Nous pourrions donc utiliser une fonction de hachage pour combiner mot de passe et poivre, avant de hacher. Est-il approprié d'utiliser sha256, ou quelle fonction de hachage serait idéale, lorsque nous voulons utiliser bcrypt par la suite?

3. Combinez mot de passe et poivre avec hmac

$passwordHash = bcrypt(hash_hmac('sha256', $password, $pepper), $salt);

Souvent, un hmac est la solution recommandée, y a-t-il un avantage par rapport à l'utilisation directe de SHA256? Puisque nous voulons seulement combiner mot de passe et poivre, et que la sécurité vient plus tard de bcrypt, je ne vois aucun avantage apparent.

Tous les conseils utiles sont très appréciés.

38
martinstoeckli

Vos trois méthodes sont correctes. Le troisième (avec HMAC) pourrait être un peu plus "élégant", mathématiquement parlant: il serait plus facile de prouver la sécurité de la construction, relativement à ceux de bcrypt et HMAC.

Attention cependant aux octets nuls. Une implémentation bcrypt donnée peut attendre un chaîne de caractères et s'arrêter au premier octet de la valeur 0, ce qui peut se produire dans la sortie de SHA-256 ou HMAC (ou dans le cadre de la clé binaire que vous utilisez comme poivre), en ignorant tous les octets suivants. Ce serait un grave problème, et vous ne le remarqueriez pas. Pour éviter ce problème, vous souhaiterez peut-être encoder en base64 la sortie SHA-256 ou HMAC avant de la donner à bcrypt (la sortie SHA-256 encodée en Base64 est de 44 caractères, toujours en dessous de la limite bcrypt).

31
Thomas Pornin