Miałem to samo pytanie, co na oryginalnym plakacie i trochę rozglądałem się i próbowałem różnych rzeczy, aby zrozumieć mechanizm. Jak już zauważyli inni, sól jest łączona z końcowym hashem. Oznacza to więc kilka rzeczy:
- Algorytm musi znać długość soli
- Musi również znać położenie soli w końcowej strunie. np. jeśli przesunięcie o określoną liczbę od lewej lub prawej strony.
Te dwie rzeczy są zwykle na stałe zakodowane w implementacji, np.źródło implementacji bcrypt dla bcryptjs definiuje długość soli na 16
var BCRYPT_SALT_LEN = 16;
Aby więc zilustrować podstawową koncepcję stojącą za pomysłem, gdyby ktoś chciał zrobić to ręcznie, wyglądałoby to podobnie do poniższego. Nie polecam samodzielnego wdrażania takich rzeczy, gdy istnieją biblioteki, które możesz to zrobić.
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);
}
var shar2 = function(str) {
}
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);
}
var encryptPassword = function(user)
{
hash(user.pass, function(err, passwordHash){
user.pass = passwordHash;
});
return user;
}
var checkPassword = function(passwordText, user)
{
compare(passwordText, user.pass, function(result){
if (result){
console.log('Correct Password');
}
else {
console.log('Incorrect Password');
}
});
}