Ответ 1
Соль включается в хеш (в виде открытого текста). Функция сравнения просто вытаскивает соль из хеша, а затем использует ее для хеширования пароля и выполнения сравнения.
От 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
});
Сверху, как не могут быть солевые значения, участвующие в сравнениях? Что мне здесь не хватает?
Соль включается в хеш (в виде открытого текста). Функция сравнения просто вытаскивает соль из хеша, а затем использует ее для хеширования пароля и выполнения сравнения.
У меня был такой же вопрос, как и оригинальный плакат, и он немного огляделся и попробовал разные вещи, чтобы понять механизм. Как уже указывалось другими, соль конкатенируется с окончательным хешем. Таким образом, это означает пару вещей:
Эти две вещи обычно жестко закодированы в реализации, например. источник реализации bcrypt для bcryptjs определяет длину соли как 16
/**
* @type {number}
* @const
* @private
*/
var BCRYPT_SALT_LEN = 16;
Итак, чтобы проиллюстрировать основную концепцию идеи, если вы хотите сделать это вручную, она будет похожа на приведенную ниже. Я не рекомендую реализовывать такие вещи, как это, когда есть библиотеки, которые вы можете сделать для этого.
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 e.g. 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');
}
});
}