node.bcrypt.js如何比较没有盐的散列和明文密码?

来自github :

哈希密码:

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

检查密码:

 // 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 }); 

从上面来看,比较中怎么没有盐值? 我在这里错过了什么?

盐被合并到散列(作为明文)。 比较函数只需从哈希中提取盐,然后使用它来散列密码并执行比较。

我也和原来的海报有同样的问题,只是看了一下四周,尝试不同的东西来理解这个机制。 正如其他人已经指出的,盐被连接到最后的散列。 所以这意味着一些事情:

  1. 该algorithm必须知道盐的长度
  2. 还必须知道最终string中盐的位置。 例如,如果从左侧或右侧偏移了特定的数字。

这两个东西通常在实现中被硬编码,例如bcryptjs的bcrypt实现源将salt长度定义为16

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

所以为了说明这个想法背后的基本概念,是否需要手动完成,看起来和下面类似。 我不build议你自己实现这样的东西,当有图书馆,你可以做到这一点。

 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'); } }); }