1. ホーム
  2. security

[解決済み] bcryptはどうして塩を内蔵しているのですか?

2022-03-14 14:44:11

質問

Coda Haleの記事 パスワードの安全な保管方法について は、次のように主張しています。

bcryptはレインボーテーブル攻撃を防ぐためにソルトを内蔵しています。

を挙げている。 本論文 という実装は、OpenBSD の bcrypt :

OpenBSDは、128ビットのbcryptソルトをarcfourから生成します。 (arc4random(3))のキーストリームに、カーネルがランダムなデータをシードしています。 デバイスのタイミングから収集したものです。

どうしてこんなことができるのか、理解できない。私のソルトの概念では。

  • 保存されたパスワードごとに異なる必要があるため、それぞれ別のレインボーテーブルを生成する必要があります。
  • ユーザーがログインしようとしたときに、そのパスワードを取得し、最初にパスワードを保存したときと同じソルトアンドハッシュ処理を繰り返し、そのパスワードを比較します。

Devise(Railsのログインマネージャ)をbcryptと一緒に使っているとき、データベースにsaltカラムがないので、混乱しているんだ。ソルトがランダムで、どこにも保存されていない場合、どのようにして確実にハッシュ処理を繰り返すことができるでしょうか?

要するに どうしてbcryptは塩を内蔵しているのでしょうか? ?

解決方法は?

これはbcryptです。

ランダムなソルトを生成します。コスト係数があらかじめ設定されています。パスワードを収集します。

ソルトとコストファクターを使って、パスワードから暗号鍵を導出する。それを使って、よく知られた文字列を暗号化する。 店舗 コスト 塩を使用します。 と暗号文があります。この3つの要素は長さが既知なので、連結して1つのフィールドに格納し、後で分割することも簡単にできます。

誰かが認証しようとしたら、保存されているコストとソルトを取得する。入力されたパスワード、コスト、ソルトから鍵を導出する。同じよく知られた文字列を暗号化する。生成された暗号文が保存されている暗号文と一致すれば、そのパスワードは一致したことになる。

Bcryptは、PBKDF2のようなアルゴリズムに基づく従来のスキームと非常によく似た方法で動作します。主な違いは、既知の平文を暗号化するために導出鍵を使用する点です。他の方式では、鍵導出関数が不可逆であると仮定し、導出鍵を直接保存します。


データベースに格納される bcrypt "hash"は次のようなものです。

<ブロッククオート

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

これは実際には3つのフィールドで、"$"で区切られています。

  • 2a を識別します。 bcrypt アルゴリズムのバージョンです。
  • 10 はコスト係数で、2 10 鍵の導出関数を繰り返し使用します(ちなみにこれは十分ではありません。12以上のコストをお勧めします)。
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa はソルトと暗号文を連結し、修正Base-64でエンコードしたものです。最初の22文字がデコードされ、16バイトのソルトの値になります。残りの文字は、認証のために比較される暗号文である。

この例は Coda Haleのruby実装のドキュメントです。