コーダ・ヘイルの記事「パスワードを安全に保存する方法」次のように主張する。
bcrypt には、レインボー テーブル攻撃を防ぐためのソルトが組み込まれています。
彼は引用するこの紙は、OpenBSD の の実装では次のようになると述べていますbcrypt
。
OpenBSD は、カーネルがデバイスのタイミングから収集したランダム データをシードとして、arcfour (arc4random(3)) キー ストリームから 128 ビットの bcrypt ソルトを生成します。
これがどのように機能するのか理解できません。私の塩の概念では、
- 保存されたパスワードごとに異なる必要があるため、それぞれに別のレインボーテーブルを生成する必要があります。
- 繰り返し使用できるようにどこかに保存する必要があります。ユーザーがログインしようとすると、パスワードの試行を取得し、パスワードを最初に保存したときと同じソルトとハッシュの手順を繰り返し、比較します。
Devise (Rails ログイン マネージャー) を bcrypt とともに使用している場合、データベースに salt 列がないので混乱します。salt がランダムでどこにも保存されていない場合、ハッシュ プロセスを確実に繰り返すにはどうすればよいでしょうか。
つまり、bcrypt にソルトを組み込むにはどうすればよいのでしょうか?
ベストアンサー1
これは bcrypt です:
ランダムなソルトを生成します。「コスト」係数は事前に設定されています。パスワードを収集します。
ソルトとコスト係数を使用して、パスワードから暗号化キーを導出します。これを使用して、既知の文字列を暗号化します。コスト、ソルト、暗号テキストを保存します。これら 3 つの要素の長さは既知であるため、連結して 1 つのフィールドに保存するのは簡単ですが、後で分割することもできます。
誰かが認証を試みるとき、保存されているコストとソルトを取得します。入力されたパスワード、コスト、ソルトからキーを導出します。同じ既知の文字列を暗号化します。生成された暗号文が保存されている暗号文と一致する場合、パスワードは一致します。
Bcrypt は、PBKDF2 などのアルゴリズムに基づく従来の方式と非常によく似た方法で動作します。主な違いは、既知のプレーン テキストを暗号化するために派生キーを使用することです。他の方式では、キー派生関数は不可逆であると (当然ながら) 想定し、派生キーを直接保存します。
データベースに保存されるbcrypt
「ハッシュ」は次のようになります。
$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
これは実際には「$」で区切られた 3 つのフィールドです。
2a
使用されたアルゴリズムのバージョンを識別しますbcrypt
。10
はコスト要因です。キー導出関数の 2 10 回の反復が使用されます (ただし、これは十分ではありません。コストは 12 以上をお勧めします)。vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
ソルトと暗号文が連結され、修正された Base-64 でエンコードされます。最初の 22 文字は、ソルトの 16 バイト値にデコードされます。残りの文字は、認証のために比較される暗号文です。