Z github :
Aby zaszyfrować hasło:
var bcrypt = require('bcrypt');
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash("B4c0/\/", salt, function(err, hash) {
// Store hash in your password DB.
});
});
Aby sprawdzić hasło:
// 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
});
Jak patrząc z góry, w porównaniach nie mogą występować wartości soli? Czego tu brakuje?
column_password = hash, column_salt = salt
vscolumn_password = hash_salt
. atakujący nadal ma te same informacje. Rzecz w tym, aby każde hasło było tak przypadkowe i większe, że jest mało prawdopodobne, aby ktoś je wstępnie obliczył.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:
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
/** * @type {number} * @const * @private */ 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); } // 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'); } }); }
źródło
Ponieważ sam miałem to samo pytanie, wiem dokładnie, o czym myślisz.
Masz błędne przekonanie między „Tajnym kluczem”, który jest używany w algorytmach kryptograficznych , a „solą”, która służy do spowolnienia procesu szyfrowania i utrudnia hakerom użycie brutalnej siły.
Kiedy używasz zwykłego hasła i soli do generowania skrótu, ten skrót używa samego hasła jako tajnego klucza ! Więc następnym razem, gdy spróbujesz porównać je ze zwykłym hasłem, musi być dokładnie tym samym hasłem, którego użyłeś do wygenerowania hasha! Dlatego nie musisz go przechowywać w innym miejscu, ponieważ jest on zawsze podawany przez użytkownika zarówno podczas rejestracji, jak i logowania!
źródło
Bcrypt porównuje zaszyfrowane i zwykłe hasła bez ciągu soli, ponieważ zaszyfrowane hasło zawiera ciąg soli, który utworzyliśmy w czasie mieszania.
Na przykład :
Weź to proste hasło:
Zaszyfrowane hasło powyższego zwykłego tekstu przy użyciu Bcrypt:
W powyższym zaszyfrowanym haśle znajdują się trzy pola rozdzielone symbolem $ .
i) Pierwsza część $ 2b $ określa używaną wersję algorytmu bcrypt.
ii) Druga część 10 $ 10 $ to czynnik kosztu (nic oprócz rund solnych podczas tworzenia sznurka soli. Jeśli zrobimy 15 rund, to wartość wyniesie 15 $
iii) Trzecia część to pierwsze 22 znaki (to nic innego jak łańcuch soli) W tym przypadku tak jest
Pozostały ciąg to zaszyfrowane hasło. Zasadniczo więc saltedHash = salt string + hashedPassword do ochrony przed atakami tęczowej tablicy.
źródło
To jest po prostu sznurek o stałej długości.
console.log(""); var salt = bcrypt.genSaltSync(10); console.log(salt); hash = bcrypt.hashSync("foobar", salt); console.log(hash); console.log(""); var salt = bcrypt.genSaltSync(10); console.log(salt); hash = bcrypt.hashSync("foobar", salt); console.log(hash); console.log(""); var salt = bcrypt.genSaltSync(10); console.log(salt); hash = bcrypt.hashSync("foobar", salt); console.log(hash);
$2a$10$onmcKV.USxnoQAsQwBFB3e $2a$10$onmcKV.USxnoQAsQwBFB3eytL3UZvZ5v/SudaWyaB9Vuq9buUqGO2 $2a$10$mwQfdyVS9dsO4SuxoR5Ime $2a$10$mwQfdyVS9dsO4SuxoR5ImeG7atz7RXGRXb.c0VHp5zSn1N2VOA.Vq $2a$10$uVUuJr6LryjchhKEg6PH7u $2a$10$uVUuJr6LryjchhKEg6PH7unTw8aJGK0i3266c5kqDBLJkf80RHEpq $2a$10$Y.upG5/54zvJyZacRxP17O $2a$10$Y.upG5/54zvJyZacRxP17OH60BC0hQRMNfQjJxSWE77fyBrbzalmS
źródło
Sól jest włączana do haszyszu. Funkcja porównania po prostu wyciąga sól z hasha, a następnie używa jej do zaszyfrowania hasła i wykonania porównania.
Kiedy użytkownik zaloguje się do naszego systemu, powinniśmy sprawdzić, czy wprowadzone hasło jest prawidłowe, czy nie. W przeciwieństwie do innych systemów, które odszyfrowałyby hasło w bazie danych (jeśli jest zaszyfrowane) i porównać je z wpisanym przez użytkownika, to, co robię z bcrypt (zakładając, że implementuje jednokierunkowe hashowanie), to zaszyfrowanie wpisanego przez użytkownik. Aby to zrobić, przekażę hasło do bcrypt, aby obliczyć hash, ale także hasło przechowywane w bazie danych skojarzonej z użytkownikiem (hash). Dzieje się tak, ponieważ, jak wspomniano wcześniej, algorytm bcrypt użył losowego segmentu (soli) do wygenerowania skrótu związanego z hasłem. Zostało to zapisane wraz z hasłem i potrzebujesz go do ponownego obliczenia skrótu hasła wprowadzonego przez użytkownika, a na koniec porównania z tym wprowadzonym podczas rejestracji i sprawdzenia, czy pasują.
źródło