AES暗号化での初期化ベクトルの使用に関する質問があります。プログラムに暗号化を組み込むために、次の記事/投稿を参照しています。
[1] Java 256ビットAESパスワードベースの暗号化
[2] http://gmailassistant.sourceforge.net/src/org/freeshell/zs/common/Encryptor.Java.html
私はもともと最初のリンクからエリクソンの解決策に従っていましたが、私が知る限り、PBKDF2WithHmacSHA1は私の実装ではサポートされていません。そこで、2番目のリンクに目を向けて、独自の反復SHA-256ハッシュ作成のアイデアを得ました。
私の質問は、IVがどのように作成されるかということです。 1つの実装([1])はCypherクラスのメソッドを使用してIVを導出し、もう1つの実装([2])はハッシュの2番目の16バイトをIVとして使用します。簡単に言えば、なぜ違いがあり、セキュリティの観点からどちらが優れているのでしょうか。 IVの導出と使用についても少し混乱しているので(微妙な違いではなく、IVが何に使用されているかを理解しています)、説明も大歓迎です。
2番目のリンクがAES-256ではなくAES-128を使用していることに気付きました。これは、この方法を使用したいのであれば、SHA-512に到達する必要があることを示唆しています。リモートで安全なハッシュを確保するには、ユーザーのパスワードを16文字長くする必要があり、このアプリは携帯電話向けであるため、これは残念な要件のようです。
ソースはまだ不完全ですが、リクエストに応じて入手できます。
前もって感謝します。
IVはパスワードだけから生成されるべきではありません。
同じキーと平文を再利用しても、異なる暗号文が生成されるというIVのポイント。 IVがパスワードのみから決定論的に生成される場合、毎回同じ暗号文を取得します。引用された例では、saltがランダムに選択されるため、同じパスワードでも新しいキーが生成されます。
乱数ジェネレーターを使用してIVを選択するだけです。それが暗号が内部で行っていることです。
IV(最初の方法を使用する場合)またはsalt(2番目の方法を使用する場合)のいずれかを暗号文と一緒に保存する必要があることを強調したいと思います。すべてがパスワードから派生している場合、セキュリティは十分ではありません。すべてのメッセージにある程度のランダム性が必要です。
私の理解では、初期化ベクトルは暗号化アルゴリズムへの単なるランダム入力です。そうでない場合、同じ入力に対して常に同じ結果が得られます。初期化ベクトルは暗号文と一緒に保存されます。これは決して秘密ではありません。安全なランダム関数を使用して、初期化ベクトルを生成するだけです。 PBKDF *アルゴリズムは、ユーザーが入力したパスワードから暗号化アルゴリズムに必要な長さの秘密鍵を導出するために使用されます。
リンク先の最初の実装では、Cipherオブジェクトに初期化ベクトルを生成させるだけです。次に、この生成されたIVをフェッチして、暗号文と一緒に保存します。
2つ目は、ハッシュバイトの一部を使用します。繰り返しのないIVを生成するアプローチで十分です。
IVの最も重要な特性は、それが繰り返されないことです(非常に頻繁に)。
暗号学者は、安全な疑似乱数ジェネレーターを使用してIVを生成する必要があります。
アプリケーション開発者は、既存の既製の暗号化を使用する必要があります。 SSLと証明書を使用してネットワークトラフィックを保護し、GPGを使用してファイルデータを保護することをお勧めします。
タイミング攻撃 など、実装を安全でなくなる可能性のある詳細がたくさんあります。アプリケーション開発者がAES128とAES256の間で決定を下しているとき、余分なキービットを役に立たなくするタイミング攻撃を残している可能性があるため、ほとんどの場合無意味です。
ここにいる他のみんなと同じように、私は常にIVが標準のアルゴリズムを使用してランダムに選択されることを知っていました。
しかし、あなたが提供した2番目の参照は、それを行っていないようです。彼はパスワードをソルトしてハッシュしているようです。次に、そのハッシュを取得して半分に分割します。半分は暗号化キーで、もう1つはIVです。したがって、IVはパスワードから派生します。
私はそのような方法に強い休憩はありませんが、それは悪いデザインです。 IVは独立していて、すべてそれ自体でランダムである必要があります。ハッシュアルゴリズムに弱点がある場合や、弱いパスワードを選択した場合などです。 IVを他のものから導き出せるようにしたくない場合、または計算前攻撃を開始することが考えられます。
IVは、ブロックチェーンの使用の結果です。これは単純なAPI設計の質問以上のものだと思います。それを使用する理由は、同じ平文が複数のブロックで同じ暗号文として表示されないようにするためであることがわかっていると思います。
N番目の暗号文ブロックが(N-1)番目のブロックなどに何らかの形で依存している最後のブロックからの再帰について考えてみてください。最初のブロックである0番目のブロックに到達したら、開始するためにいくつかのデータが必要です。復号化を試みる前にデータを知っている限り、そのデータが何であるかは問題ではありません。非秘密のランダムデータを初期化ベクトルとして使用すると、同じキーで暗号化された同一のメッセージが完全に異なる暗号文として出力されます。
概念的にはハッシュのソルトに似ています。そして、そのソースコードは私には少し怪しいように見えます。 IVは、単純にfresh-at-encryption-timeナンスのように、何にも依存しないランダムビットである必要があります。 IVは基本的に暗号化されたメッセージの一部です。同一のデータを同一のキーで再暗号化すると、メッセージを相互に関連付けることができなくなります。 (ねえ、暗号文の長さによる相関の結果についても考えてください。)