web-dev-qa-db-ja.com

暗号化キーを生成するためのPBKDF2のIVに関する説明

次の実装は本当に安全ではないことに気づきました。

$pb = pbkdf2('sha256', $_POST['pass'], "enc_salt", 100, 100);
$d = openssl_decrypt ($data['container'],'aes-192-cbc', $pb, true, $data['iv']);

実際、「enc_salt」の代わりに$ pbに固有のソルトを使用する必要がありますか?

さらに、同じIVを使用してPBKDFでキーを生成し、実際にコンテンツを暗号化することはできますか?

2

ソルトは、攻撃者によるコスト共有を防ぐためにここにあります。 2つのパスワードが同じソルトでハッシュされている場合、攻撃者はそのソルト値を使用して潜在的なパスワードをハッシュし、2つのパスワードのハッシュバージョンと出力を比較する可能性があります。つまり、攻撃者は、ハッシュされた2つのパスワードを攻撃して、1つのパスワードを攻撃することができます。これは拡大します。ハッシュされたパスワードがすべて同じソルトのものである場合、攻撃者は「無料」で999のパスワードを取得します。

この種類のコストシェアリングにはいくつかの形式があり、そのうちの1つは事前計算されたテーブルです(1つの特定の種類のテーブルは "レインボーテーブル"と呼ばれます)。一般的に、コストシェアリングは並列処理のインスタンスです(適切な時空ワープを使用)。

ソルト値をできるだけ再利用しないようにする必要があります。可能であれば、決して。あなたの場合、暗号化されたファイルと一緒にソルトを保存します。各ファイルには独自のソルト値があります(2つのファイルが同じパスワードを使用していても、それぞれに独自のソルトが必要です)。


各ファイルに独自のソルト値がある場合、IVに対して次のいずれかを実行できます。

  • ランダムなIVを選択して、ファイルヘッダーに追加します(saltとともに)。
  • PBKDF2を使用して、キーIVを一度に生成します(たとえば、256ビットの出力を要求し、キーに128、IVに128)。
  • 固定IVを使用します。

2番目と3番目のオプションは、衝突が発生しない十分に大きなスペースで、実際に各ファイルの新しいソルトを生成している場合にのみ安全です練習。そうしないと、IVの再利用につながる可能性があり、これは罪です。具体的には、本当に悪いのはTM 同じキーで2度同じIVを使用しています。各ファイルに独自のキーがある場合(そのキーはソルトを使用してパスワードを処理し、各ファイルに独自のソルトがあるため)、固定IVで問題ありません。


とにかく、暗号化が必要な場合は、整合性のチェックも必要になる可能性があります。これには [〜#〜] mac [〜#〜] が必要です。暗号化とMACを正しく組み立てるのは tricky です。適切な方法は、暗号化者を満足させる方法ですでに機能している暗号化モードを使用することです。実際には、'aes-192-gcm'ではなく'aes-192-cbc'を使用します(または'aes-128-gcm':128ビットで十分ですが、少し高速になります)。

GCMの実際のIVの長さは12バイトです。

2
Thomas Pornin

ソルトの主な目的は、レインボーテーブルの攻撃から保護することです。さまざまなシナリオがあります。

  1. ソルトを使用しない場合、攻撃者はすでにRainbowテーブルを準備してパスワードの攻撃を開始する可能性があります。
  2. すべてのエントリに同じソルトを使用する場合、攻撃者はソルトに基づいて新しいレインボーテーブルを生成する必要があり、これを使用してパスワードを攻撃できます。
  3. パスワードごとに異なるソルトを使用する場合、攻撃者は解読しようとするパスワードごとに個別のRainbowテーブルを生成する必要がありますが、これは現実的ではありません。

したがって、パスワードごとに常に異なるソルトを使用することをお勧めします。

通常、ソルトは秘密リソースとは見なされないため、データベースに暗号化されていない形式で保存できます。レインボーテーブルを使用できないようにすることが唯一の目的です。私はIVの専門家ではありませんが、私が知る限り、IVは秘密にすべきであり、IVが暗号化されていない形式でデータベースに格納されている場合は、おそらく良い考えではありません。したがって、塩としてIVを使用することはお勧めしません。

0
stanko