Node.bcrypt.js, tuz içermeyen karma ve düz metin şifrelerini nasıl karşılaştırır?


96

Gönderen github :

Bir parolaya hashing uygulamak için:

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

Bir şifreyi kontrol etmek için:

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

Yukarıdan, karşılaştırmalara nasıl tuz değerleri dahil edilmez? Burada neyi özlüyorum?

Yanıtlar:


99

Tuz, hash'e dahil edilir (düz metin olarak). Karşılaştırma işlevi, salt değerini hash'den çıkarır ve ardından parolayı hash etmek ve karşılaştırmayı gerçekleştirmek için kullanır.


1
Hâlâ anlamıyorum. Karşılaştırma sırasında, tuzu sağlamazsanız, esrarın hangi kısmının tuz olduğunu nasıl anlar?
MondayPaper

7
bcrypt bir standarttır ve her zaman tuzu karma ile aynı formatta birleştirir. Tuzu, şifrelediğinizde sağlarsınız ve bu, hash'e dahil edilir. bcrypt yalnızca başlangıçta bcrypt kullanılarak şifrelenmiş verilerin şifresini çözebilir, aksi takdirde haklısınız - hangi kısmın karma ve hangi kısmın tuz olduğunu bilmesinin bir yolu yoktur.
Bill

6
Tamam, anlıyoruz: tuz, karma ile saklanır. bcrypt açık kaynak kodludur, yani bu, herkesin onu tam olarak nasıl sakladığını bildiği anlamına gelir. Yani onu nasıl çıkaracağınızı veya düz metin şifresinden nasıl hash oluşturacağınızı biliyorsunuz. Bu, şifreleri gökkuşağı tablolarını karmalar için taramaya karşı korumaya nasıl yardımcı olur ki bu temelde tuzun arkasındaki ana fikirdir?
Vitaliy Lebedev

13
Saldırganın herhangi bir hash için tuzu bilmesi önemli değil, bu bir sır değil. Her parola için farklı bir salt kullanmak, saldırganın ortak değerleri kullanarak karmaları önceden hesaplayamayacağı anlamına gelir. Her birinde farklı bir tuzla, her şifre için herhangi bir tabloyu yeniden hesaplamaları gerekecek ve bu da onları işe yaramaz hale getirecektir.
Bill

3
: Saldırgan Böyle veri tabanında belirli bir kullanıcı için tuz biliyorsa bu şekilde bakmak, önemli mi column_password = hash, column_salt = saltvs column_password = hash_salt. saldırgan hala aynı bilgiye sahip. İşin püf noktası, her parolayı o kadar rastgele ve daha büyük hale getirmek ki, birisinin onu önceden hesaplama olasılığı çok düşük.
Muhammad Umer

27

Ben de orijinal posterle aynı soruyu sormuştum ve etrafa bakıp mekanizmayı anlamak için farklı şeyler denemek gerekti. Başkaları tarafından daha önce belirtildiği gibi, tuz son hash ile birleştirilir. Yani bu birkaç anlama geliyor:

  1. Algoritma tuzun uzunluğunu bilmelidir
  2. Ayrıca son dizideki tuzun konumunu da bilmelidir. örneğin, soldan veya sağdan belirli bir sayı ile kaymışsa.

Bu iki şey genellikle uygulamada sabit kodlanmıştır, örneğin bcryptjs için bcrypt uygulama kaynağı tuz uzunluğunu 16 olarak tanımlar.

/**
* @type {number}
* @const
* @private
*/

var BCRYPT_SALT_LEN = 16;

Dolayısıyla, fikrin arkasındaki temel kavramı göstermek için, eğer biri bunu manuel olarak yapmak isterse, aşağıdakine benzer görünecektir. Bunu yapabileceğiniz kütüphaneler varken, bu tür şeyleri kendiniz uygulamanızı önermiyorum.

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

1

Ben de aynı soruyu sorduğum için, ne düşündüğünüzü tam olarak biliyorum.

Şifreleme algoritmalarında kullanılan "Gizli Anahtar" ile şifreleme sürecini yavaşlatmak ve bilgisayar korsanlarının kaba kuvvet kullanmasını zorlaştırmak için kullanılan "Salt" arasında bir yanlış anlama var .

Karma oluşturmak için düz şifreyi ve tuzu kullandığınızda , bu karma şifrenin kendisini gizli anahtar olarak kullanır ! Yani bir dahaki sefere onu düz bir parola ile karşılaştırmaya çalıştığınızda, bu düz parola, hash'i oluşturmak için kullandığınızla aynı olmalıdır! Bu yüzden onu başka bir yerde saklamanıza gerek yok çünkü her zaman kullanıcı tarafından hem kayıt hem de oturum açma adımlarında sağlanır!


1

Bcrypt, karma ve düz metin şifrelerini salt dizesi olmadan karşılaştırır çünkü karma şifre, karma işlemi sırasında oluşturduğumuz tuz dizesini içerir.

Örneğin :

Bu Düz Şifreyi alın:

546456546456546456456546111

Bcrypt kullanarak yukarıdaki düz metnin Hashed Şifresi:

$ 2b $ 10 $ uuIKmW3Pvme9tH8qOn / H7uZqlv9ENS7zlIbkMvCSDIv7aup3WNH9W

Dolayısıyla, yukarıdaki karma şifrede, $ simgesiyle ayrılmış üç alan vardır .

i) Birinci Bölüm $ 2b $ , kullanılan bcrypt algoritması sürümünü tanımlar.

ii) İkinci Kısım 10 $ 10 maliyet faktörüdür (tuz dizisini oluştururken tuz turlarından başka bir şey değildir. 15 tur yaparsak, değer 15 $ olur

iii) Üçüncü Bölüm ilk 22 karakterdir (bu, salt dizisinden başka bir şey değildir) Bu durumda

uuIKmW3Pvme9tH8qOn / H7u

Kalan dize, karma şifredir. Yani temel olarak, gökkuşağı tablo saldırılarından korunmak için tuzluHash = salt string + hashedPassword.


1

Bu sadece sabit uzunlukta bir dizedir.

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

0

Tuz, hash'e dahil edilir. Karşılaştırma işlevi, salt değerini hash'den çıkarır ve ardından parolayı hash etmek ve karşılaştırmayı gerçekleştirmek için kullanır.

Bir kullanıcı sistemimize giriş yaptığında, girilen şifrenin doğru olup olmadığını kontrol etmeliyiz. Veritabanındaki parolanın şifresini çözen (şifrelenmişse) ve kullanıcı tarafından girilenle karşılaştıran diğer sistemlerin aksine, bcrypt ile yaptığım şey (tek yönlü hashing uyguladığı sürece) tarafından girileni şifrelemek. kullanıcı. Bunu yapmak için, hash'i hesaplamak için şifreyi bcrypt'e geçireceğim, aynı zamanda kullanıcıyla ilişkili veritabanında depolanan şifreyi (karma) da ileteceğim. Bunun nedeni, daha önce bahsedildiği gibi, bcrypt algoritmasının parola ile ilişkili hash'i oluşturmak için rastgele bir segment (salt) kullanmasıdır. Bu, parola ile birlikte saklandı ve kullanıcı tarafından girilen parolanın karmasını yeniden hesaplamak ve son olarak kayıt olurken girilenle karşılaştırmak ve eşleşip eşleşmediklerini görmek için buna ihtiyacınız var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.