web-dev-qa-db-ja.com

Laravel 5:同じ文字列でbcryptを使用すると、異なる値が得られます

パスワードのハッシュにLaravelのbcrypt関数を使用しています。私がする時、

bcrypt('secret')

私は得る

=> "$2y$10$mnPgYt2xm9pxb/c2I.SH.uuhgrOj4WajDQTJYssUbTjmPOcgQybcu"

しかし、もう一度実行すると、

=> "$2y$10$J8h.Xmf6muivJ4bDweUlcu/BaNzI2wlBiAcop30PbPoKa0kDaf9xi"

等々...

では、毎回異なる値を取得した場合、パスワード照合プロセスは失敗しませんか?

13
user6737580

これがbcryptの動作方法です。 wikipedia を参照してください。

Bcryptはハッシュ中にランダム128ビットソルトを生成します。このsaltはハッシュの一部になるため、同じ入力文字列に対して常に異なるハッシュ値を取得します。ランダムソルトは、実際にはブルートフォース攻撃を阻止するために使用されます。

ハッシュの値が異なるため、パスワード照合プロセスが失敗することはありません。 tinkerで以下を試してください

$hash1 = bcrypt('secret')
$hash2 = bcrypt('secret')

Hash::check('secret', $hash1)
Hash::check('secret', $hash2)

Hash::checkのどちらの場合もtrueを取得する必要があります。

したがって、ハッシュ値が異なっていても、パスワードの照合は失敗しません。

24
linuxartisan

Bcryptは128ビットのソルトを使用し、192ビットのマジック値を暗号化します。 eksblowfishの高価なキー設定を利用します。

Bcryptアルゴリズムは、図3に示す2つのフェーズで実行されます。最初のフェーズでは、eksblowfishの状態を初期化するために、コスト、ソルト、およびパスワードを指定してEksBlowfishSetupが呼び出されます。 bcryptの時間のほとんどは、高価な鍵スケジュールに費やされています。その後、192ビット値「OrpheanBeholderScryDoubt」は、前のフェーズの状態でECBモードのeksblowfishを使用して64回暗号化されます。出力は、暗号化ループの結果と連結されたコストと128ビットのソルトです。

enter image description here

それがどのように機能するかlaravel:

if (! function_exists('bcrypt')) {
    /**
     * Hash the given value against the bcrypt algorithm.
     *
     * @param  string  $value
     * @param  array  $options
     * @return string
     */
    function bcrypt($value, $options = [])
    {
        return app('hash')->driver('bcrypt')->make($value, $options);
    }
}

PASSWORD_BCRYPTのサポートされるオプション:

salt(string)-パスワードをハッシュするときに使用するソルトを手動で提供します。これは上書きされ、ソルトが自動的に生成されるのを防ぎます。

省略した場合、ランダムなソルトは、ハッシュされたパスワードごとにpassword_hash()によって生成されます。これは意図された動作モードです。

警告saltオプションは、PHP 7.0.0)で廃止されました。デフォルトで生成されるsaltを使用することが推奨されます。

cost(integer)-使用するアルゴリズムコストを示します。これらの値の例は、crypt()ページにあります。

省略した場合、デフォルト値の10が使用されます。これは適切なベースラインコストですが、ハードウェアによっては増やすことを検討してください。

Bcryptの暗号化と復号化の仕組み:
内部でbcrypt()を使用するには、PHPの組み込みのpassword_hash()関数を使用します。 password_hash()は、ランダムな文字列(「塩」)をパスワードに追加するため、毎回異なる値を返します。ソルトは実際には出力ハッシュに含まれています。

同じパスワードが同じソルトでハッシュされている場合、常に同じ出力が得られます。したがって、password_verify()は格納されているハッシュを調べてソルトを抽出し、同じソルトで指定されたパスワードをハッシュします。

1
Amitesh