web-dev-qa-db-ja.com

AESを使用してデータベースのパスワードを暗号化する場合、Salt、IV、およびKeyは必要ですか?もしそうなら、それらはどのように使用されるべきですか?

ユーザーアカウントのあるWebサイトがあるとします。ユーザーを認証したいので、ユーザーが提供するパスワードがデータベースに保存されているパスワードと一致するかどうかを知る必要があります。パスワードをのぞき見から保護するために、それらを難読化したいので、CBCモードでAESを使用してそうすることにします。

AES-CBCを使用してこれを行うべきではないことはわかっています。おそらく暗号化アルゴリズムではなくハッシュアルゴリズムを使用する必要がありますが、この事実は無視してください。そうすれば、理解が深まります。

AES-CBCを使用してデータベースに保存するためにユーザーパスワードを暗号化する場合、キー、IV、およびソルトを使用する必要がありますか?私が使用する必要があるものは何でも、それらはどのように正確に使用されますか?

私の問題をよりよく説明するために例を挙げます:

ユーザー名「bob」のユーザーは、パスワード「mypass」でサインアップします

AES-CBCを使用してこのパスワードを難読化する最も安全な方法を決定する必要があります。

現在、これを行うには、CSPRNG [1]を使用して16バイトのソルトを生成する必要があると思います。ソルトの前にユーザーパスワードを付加する必要があります:salt + "mypass"。ハードコードされた256ビットのキーとランダムに生成された16バイトのIVを使用するAES-CBCを使用して、salt + "mypass"を暗号化する必要があります。

実質的に私は:AesEncrypt(salt + "mypass"、GenerateIv()、Key)

この例を与えられて、私は私を混乱させるいくつかのポイントを持っています。

1)私がAESに渡すランダムIVは、2つの「mypass」が同じ暗号文を与えないという効果があります。ソルトのポイントは「mypass」の2つの暗号文が同一になるのを防ぐことなので、これはソルティングを冗長にしませんか?

2)逆に、IVが冗長であり、パスワードをソルトしているので、ゼロIVまたは定数IVを渡すことができますか?

3)IVはソルトではなくXORされているため、両方とも有用であることを本当に理解せずに読んだため、IVとソルトは冗長ではないとします。 「mypass」の前に塩を付けるだけで、適切に塩漬けするだけで十分ですか?

4)AESで「mypass」を暗号化するために使用するキーを派生させるために、どういうわけかソルトを使用することになっていますか?それとも、ハードコードされたキーを使用するだけで正しくできていますか?

5)データベースには何を保存する必要がありますか? salt、iv、暗号文をすべて個別の列に格納する必要がありますか、それとも何らかの方法で組み合わせる必要がある場合は、単純な連結で十分ですか、それとも特別な関数と組み合わせる必要がありますか?

6)私は完全に間違っていますか?そうである場合、代わりに何をすべきですか?

ありがとうございました。

=============

[1]暗号的に安全な疑似乱数ジェネレータ

7
Didier A.

ソルトとIVは冗長です。どちらも同じタイプの攻撃から保護し(2つのアカウントが同じパスワードを持っていることを発見し)、同じ方法で(パスワードの暗号化された表現を作成することにより)異なる)。

1
Mark

AES-CBCを使用してデータベースに保存するためにユーザーパスワードを暗号化する場合、キー、IV、およびソルトを使用する必要がありますか?私が使用する必要があるものは何でも、それらはどのように正確に使用されますか?

IVは、AES-CBC暗号化スキームの最初の16バイトマトリックスを初期化するために使用されます。メッセージの最初の16バイトとXORされます。つまり、IVが一定の場合、同じメッセージが常に同じ暗号文を出力します。一方、同じメッセージの暗号化の実行ごとにIVが異なる場合、最初のブロックとIVのXORが行われるため、XORは異なりますIVはAES-CBCの固有の部分であり、常にIVを使用する必要があります。このIVが一定であるかどうかです。

Saltは、実際のメッセージの前に付加するランダムメッセージです。そのため、実際のメッセージをエンコードするたびに、実際には異なる見た目のメッセージ(塩+実際のメッセージ)をエンコードして、異なる暗号文を生成します。これは通常、同じメッセージのハッシュの実行ごとに異なるハッシュを取得するために、ハッシュアルゴリズムに使用されます。

AES-CBCでソルトを使用する必要はありません。これは、IVがすでにソルトの設計どおりの効果を持っているためです。しかし、塩を使用したい場合は、使用できます。これがどうなるかです。 16バイトのソルトがあるとすると、メッセージの前に付加されるため、AES-CBCで暗号化する入力として(塩+メッセージ)を使用します。 16バイトなので、ソルトはAES-CBCの最初のブロックに収まり、IVとXORされ、結果として(salt XOR iv)になります。この(salt XOR iv)は、2番目のブロックのIVとして使用されます。これは、この場合、実際のメッセージの最初の16バイトです。

したがって、AES-CBCの場合、ソルトを使用しても、IVに追加の処理が行われるだけです。 IVが一定の場合、saltはXORと一緒になり、IVが一定であっても、暗号化の実行ごとに異なる2番目のブロックへの新しいIVになります。

したがって、結論としては、ランダムIVを使用し、ソルトをまったく使用しない方がよいでしょう。または、定数IVを使用してランダムなソルトを使用します(ただし、これには注意してください。詳細については、下記の#2を参照してください)。これらはどちらも同じ効果があります。つまり、同じメッセージの暗号化の実行ごとに異なる暗号文を生成します。

1)私がAESに渡すランダムIVは、2つの「mypass」が同じ暗号文を与えないという効果があります。ソルトのポイントは「mypass」の2つの暗号文が同一になるのを防ぐことなので、これはソルティングを冗長にしませんか?

はい、そうです。 IVとソルトには効果的に同じ効果があり、同じ攻撃からの保護に役立ちます。 saltが同じ効果を持つためには、その実装での適切な考慮を考慮する必要があることに注意してください。詳細については、下記の#2を参照してください。

2)逆に、IVが冗長であり、パスワードをソルトしているので、ゼロIVまたは定数IVを渡すことができますか?

そんなに早くない。これを実現するには、多くのことを適切に組み合わせる必要があります。 AESのモードによっては、塩漬けによって望ましい動作が得られるとは限らない場合があります。ソルトの長さと、メッセージと連結する方法も正しくなければなりません。たとえば、追加すると、長いパスワードで問題が発生する可能性があります。したがって、考えられていたとおりにAESを使用することをお勧めします。つまり、ランダムIVを使用し、塩は使用しません。

3)IVはソルトではなくXORされているため、両方とも有用であることを本当に理解せずに読んだため、IVとソルトは冗長ではないとします。 「mypass」の前に塩を付けるだけで、適切に塩漬けするだけで十分ですか?

IVは、暗号化されるモードCBCのAESの最初のブロックとXORされます。ソルトを使用する場合、ソルトは最初のブロックでIVとXORされ、これ(IV xorソルト)は事実上2番目のIVとなり、16バイトのソルトが与えられた場合、実際のメッセージが暗号化されます。 。

4)AESで「mypass」を暗号化するために使用するキーを派生させるために、どういうわけかソルトを使用することになっていますか?それとも、ハードコードされたキーを使用するだけで正しくできていますか?

塩から鍵を派生させるべきではありません。ソルトは秘密ではないので、そうした場合、キーは非秘密のソルトから簡単に見つけることができます。これをパスワードベースの暗号化と混同していました。そこでは、キー導出関数を使用して秘密のパスワードからキーを派生させています。

5)データベースには何を保存する必要がありますか? salt、iv、暗号文をすべて個別の列に格納する必要がありますか、それとも何らかの方法で組み合わせる必要がある場合は、単純な連結で十分ですか、それとも特別な関数と組み合わせる必要がありますか?

あなたがそれらを取得する方法を知っている限り、私が理解したことから、これは問題ではありません。別の列を使用するか、何らかの方法でそれらを1つに組み合わせることができます。

6)私は完全に間違っていますか?

基本的に、私はハッシュ関数としてAES-CBCを使用しています。通常、AESの256ビットキーはブルートフォースが非常に難しいことを意味しますが、ここではメッセージの組み合わせをブルートフォースできるため、これは回避されます。力。

もう1つの問題は、対称アルゴリズムであるため、ハッカーがサーバーを危険にさらしてキーを取得した場合、ブルートフォース、辞書攻撃、レインボーテーブルなどを必要とせず、すべてのパスワードを解読できることです。

8
Didier A.