私はAndroidでPBEのAES暗号化エンジンを実装しています。IVの作成を実装する2つの方法を見つけました。IvParameterSpec
を取得するために、どちらがより適切で安全かを知りたいです。
方法#1:
SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
方法#2:
AlgorithmParameters params = cipher.getParameters();
byte[] iv2 = params.getParameterSpec(IvParameterSpec.class).getIV();
ivParams = new IvParameterSpec(iv2);
Java APIがCipher.init()
APIに対して以下を指定するため、メソッド#1を使用します暗号化/復号化モードとキー:
この暗号インスタンスが、指定されたキーでは提供できないアルゴリズムパラメータまたはランダムな値を必要とする場合、この暗号の基本となる実装は、プロバイダを使用して必要なパラメータ(を生成することになっていますまたはランダムな値)。
(強調鉱山)。
したがって、明確ではありませんメソッド2が選択されている場合に、異なるプロバイダーが何をするかです。 Androidソースコードで、少なくともいくつかのバージョン(バージョン21を含む?)はランダムIVを作成しないようです-ランダムIV作成はコメントアウトされているようです。
方法1も透明性が高く、私の意見では目に優しいです。
一般的にはnew SecureRandom()
を使用して、どのRNGが最適かをシステムに判断させる方がよいことに注意してください。 "SHA1PRNG"
は明確に定義されておらず、実装によって異なる可能性があり、既知の実装に実装の弱点があること、特にAndroidの場合。
したがって、最終結果は次のようになります。
SecureRandom randomSecureRandom = new SecureRandom();
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
GCMモードは、AESのブロックサイズである16バイトのIVではなく、12バイトのIVで最適に機能することに注意してください。