次の実装は本当に安全ではないことに気づきました。
$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つのパスワードを攻撃して、1つのパスワードを攻撃することができます。これは拡大します。ハッシュされたパスワードがすべて同じソルトのものである場合、攻撃者は「無料」で999のパスワードを取得します。
この種類のコストシェアリングにはいくつかの形式があり、そのうちの1つは事前計算されたテーブルです(1つの特定の種類のテーブルは "レインボーテーブル"と呼ばれます)。一般的に、コストシェアリングは並列処理のインスタンスです(適切な時空ワープを使用)。
ソルト値をできるだけ再利用しないようにする必要があります。可能であれば、決して。あなたの場合、暗号化されたファイルと一緒にソルトを保存します。各ファイルには独自のソルト値があります(2つのファイルが同じパスワードを使用していても、それぞれに独自のソルトが必要です)。
各ファイルに独自のソルト値がある場合、IVに対して次のいずれかを実行できます。
2番目と3番目のオプションは、衝突が発生しない十分に大きなスペースで、実際に各ファイルの新しいソルトを生成している場合にのみ安全です練習。そうしないと、IVの再利用につながる可能性があり、これは罪です。具体的には、本当に悪いのはTM 同じキーで2度同じIVを使用しています。各ファイルに独自のキーがある場合(そのキーはソルトを使用してパスワードを処理し、各ファイルに独自のソルトがあるため)、固定IVで問題ありません。
とにかく、暗号化が必要な場合は、整合性のチェックも必要になる可能性があります。これには [〜#〜] mac [〜#〜] が必要です。暗号化とMACを正しく組み立てるのは tricky です。適切な方法は、暗号化者を満足させる方法ですでに機能している暗号化モードを使用することです。実際には、'aes-192-gcm'
ではなく'aes-192-cbc'
を使用します(または'aes-128-gcm'
:128ビットで十分ですが、少し高速になります)。
GCMの実際のIVの長さは12バイトです。
ソルトの主な目的は、レインボーテーブルの攻撃から保護することです。さまざまなシナリオがあります。
したがって、パスワードごとに常に異なるソルトを使用することをお勧めします。
通常、ソルトは秘密リソースとは見なされないため、データベースに暗号化されていない形式で保存できます。レインボーテーブルを使用できないようにすることが唯一の目的です。私はIVの専門家ではありませんが、私が知る限り、IVは秘密にすべきであり、IVが暗号化されていない形式でデータベースに格納されている場合は、おそらく良い考えではありません。したがって、塩としてIVを使用することはお勧めしません。