113

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

上記から、比較に塩の値が含まれないようにするにはどうすればよいですか?ここで何が欠けていますか?

4

6 に答える 6

111

ソルトは(プレーンテキストとして)ハッシュに組み込まれます。比較関数は、ハッシュからソルトを引き出し、それを使用してパスワードをハッシュし、比較を実行するだけです。

于 2012-10-23T06:00:12.363 に答える
30

元のポスターと同じ質問がありましたが、メカニズムを理解するために、周りを見回してさまざまなことを試してみました。他の人がすでに指摘しているように、ソルトは最終的なハッシュに連結されます。つまり、これはいくつかのことを意味します。

  1. アルゴリズムはソルトの長さを知っている必要があります
  2. 最後の文字列の塩の位置も知っている必要があります。たとえば、左または右から特定の数だけオフセットされている場合。

これらの2つは通常、実装にハードコーディングされています。たとえば、 bcryptjsのbcrypt実装ソースでは、ソルトの長さを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');
        }
    });
}
于 2014-05-24T05:23:27.130 に答える
15

ハッシュされたパスワードにはハッシュ時に作成したソルト文字列が含まれているため、Bcryptはソルト文字列なしでハッシュされたパスワードとプレーンテキストのパスワードを比較します。

例えば ​​:

このプレーンパスワードを取る:

546456546456546456456546111

Bcryptを使用した上記のプレーンテキストのハッシュパスワード:

$ 2b $ 10 $ uuIKmW3Pvme9tH8qOn / H7uZqlv9ENS7zlIbkMvCSDIv7aup3WNH9W

したがって、上記のハッシュされたパスワードには、 $記号で区切られた3つのフィールドがあります。

i)最初の部分$ 2b $は、使用されるbcryptアルゴリズムのバージョンを識別します。

ii)2番目の部分$ 10 $ 10はコスト要因です(ソルトストリングの作成中はソルトラウンドのみです。15ラウンドを実行すると、値は$15$になります。

iii)3番目の部分は最初の22文字です(つまり、ソルトストリングにすぎません)この場合は

uuIKmW3Pvme9tH8qOn / H7u

残りの文字列はハッシュ化されたパスワードです。つまり、基本的に、saltedHash = salt string + hashedPasswordは、レインボーテーブル攻撃から保護します。

于 2020-10-21T05:44:50.033 に答える
4

私自身も同じ質問をしたので、あなたが何を考えているのかを正確に知っています。

暗号化アルゴリズムで使用される「秘密鍵」と、暗号化プロセスを遅くし、ハッカーがブルートフォースを使用しにくくするために使用される「ソルト」との間に誤解があります。

プレーンパスワードとソルトを使用してハッシュを生成する場合、このハッシュは秘密鍵としてパスワード自体を使用します。したがって、次にプレーンパスワードと比較しようとするときは、このプレーンパスワードは、ハッシュの生成に使用したものとまったく同じである必要があります。これが、登録とログインの両方のステップで常にユーザーによって提供されるため、別の場所に保存する必要がない理由です。

于 2020-04-11T19:58:24.057 に答える
2

固定長の文字列です。

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
于 2020-10-27T19:38:12.880 に答える
1

塩はハッシュに組み込まれます。比較関数は、ハッシュからソルトを引き出し、それを使用してパスワードをハッシュし、比較を実行するだけです。

ユーザーがシステムにログインするときは、入力したパスワードが正しいかどうかを確認する必要があります。データベース内のパスワードを復号化し(暗号化されている場合)、ユーザーが入力したものと比較する他のシステムとは異なり、bcrypt(一方向ハッシュを実装している場合)で行うことは、ユーザー。これを行うには、パスワードをbcryptに渡してハッシュを計算しますが、ユーザーに関連付けられたデータベース(ハッシュ)に保存されているパスワードも渡します。これは、前述のように、bcryptアルゴリズムがランダムセグメント(ソルト)を使用してパスワードに関連付けられたハッシュを生成したためです。これはパスワードと一緒に保存されており、ユーザーが入力したパスワードのハッシュを再計算し、最終的に登録時に入力したものと比較して、一致するかどうかを確認するために必要です。

于 2020-10-15T18:08:24.803 に答える