Comment node.bcrypt.js compare-t-il les mots de passe hachés et les mots de passe en clair sans le sel?

De github :

Pour hacher un mot de passe:

var bcrypt = require('bcrypt'); bcrypt.genSalt(10, function(err, salt) { bcrypt.hash("B4c0/\/", salt, function(err, hash) { // Store hash in your password DB. }); }); 

Pour vérifier un mot de passe:

 // Load hash from your password DB. bcrypt.compare("B4c0/\/", hash, function(err, res) { // res == true }); bcrypt.compare("not_bacon", hash, function(err, res) { // res = false }); 

De là-dessus, comment les valeurs de comparaison peuvent-elles être absentes? Qu’est-ce que j’oublie ici?

Le sel est incorporé dans le hash (en clair). La fonction de comparaison extrait simplement le sel du hachage et l’utilise ensuite pour hacher le mot de passe et effectuer la comparaison.

J’ai eu la même question que l’affiche originale et il a fallu un peu regarder autour de moi et essayer différentes choses pour comprendre le mécanisme. Comme cela a déjà été souligné par d’autres, le sel est concaténé au hachage final. Donc, cela signifie deux choses:

  1. L’algorithme doit connaître la longueur du sel
  2. Doit également connaître la position du sel dans la chaîne finale. par exemple si compensé par un nombre spécifique de gauche ou de droite.

Ces deux choses sont généralement codées en dur dans l’implémentation, par exemple la source d’implémentation de bcrypt pour bcryptjs définit la longueur du sel comme 16

 /** * @type {number} * @const * @private */ var BCRYPT_SALT_LEN = 16; 

Donc, pour illustrer le concept de base de l’idée si l’on voulait le faire manuellement, cela ressemblerait à ce qui suit. Je ne recommande pas d’implémenter ce genre de choses quand il ya des bibliothèques que vous pouvez faire pour le faire.

 var salt_length = 16; var salt_offset = 0; var genSalt = function(callback) { var alphaNum = '0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ'; var salt = ''; for (var i = 0; i < salt_length; i++) { var j = Math.floor(Math.random() * alphaNum.length); salt += alphaNum[j]; } callback(salt); } // cryptographic hash function of your choice eg shar2 // preferably included from an External Library (dont reinvent the wheel) var shar2 = function(str) { // shar2 logic here // return hashed string; } var hash = function(passwordText, callback) { var passwordHash = null; genSalt(function(salt){ passwordHash = salt + shar2(passwordText + salt); }); callback(null, passwordHash); } var compare = function(passwordText, passwordHash, callback) { var salt = passwordHash.substr(salt_offset, salt_length); validatedHash = salt + shar2(passwordText + salt); callback(passwordHash === validatedHash); } // sample usage var encryptPassword = function(user) { // user is an object with fields like username, pass, email hash(user.pass, function(err, passwordHash){ // use the hashed password here user.pass = passwordHash; }); return user; } var checkPassword = function(passwordText, user) { // user has been returned from database with a hashed password compare(passwordText, user.pass, function(result){ // result will be true if the two are equal if (result){ // succeeded console.log('Correct Password'); } else { // failed console.log('Incorrect Password'); } }); }