8

私はJavaでAESを実装しようとしていますが、これは私が使用するコードです。

 byte[] sessionKey = {00000000000000000000000000000000};
 byte[] iv = {00000000000000000000000000000000};
 byte[] plaintext = "6a84867cd77e12ad07ea1be895c53fa3".getBytes();
 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

 cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
 byte[] ciphertext = cipher.doFinal(plaintext);

 cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
 byte[] deciphertext = cipher.doFinal(ciphertext);

テスト目的でこの固定キーとIVが必要ですが、次の例外が発生します。

Exception in thread "main"
java.security.InvalidAlgorithmParameterException: 
  Wrong IV length: must be 16 bytes long    at
com.sun.crypto.provider.SunJCE_h.a(DashoA12275)     at
com.sun.crypto.provider.AESCipher.engineInit(DashoA12275)   at
javax.crypto.Cipher.a(DashoA12275)  at
javax.crypto.Cipher.a(DashoA12275)  at
javax.crypto.Cipher.init(DashoA12275)   at
javax.crypto.Cipher.init(DashoA12275)

この固定IVをこのAESの実装でどのように使用できますか?方法はありますか?

4

6 に答える 6

42

まず、

byte[] iv = {00000000000000000000000000000000};

サイズ32のバイト配列ではなく、サイズ1のバイト配列を作成します(それが意図した場合)。

次に、AESのIVサイズは16バイトまたは128ビット(AES-128のブロックサイズ)である必要があります。AES-256を使用する場合、AES標準では128ビットのブロックサイズのみが許可されているため、IVサイズは128ビットの大きさにする必要があります。元のRijndaelアルゴリズムでは、256ビット長のブロックサイズを含む他のブロックサイズが許可されていました。

第三に、AES-256を使用する場合、これはそのままではありません。JCE Unlimited Strength Jurisdiction Policy Filesをダウンロードしてインストールする必要があります(ページの一番下までスクロールします)。付属のライセンスも読むことをお勧めします。

これにより、コードが次のように変更されます。

byte[] iv = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

最後に、初期化ベクトルは一意で予測不可能であることが意図されています。各バイトが値0で表される16バイトのシーケンスは、IVの適切な候補ではありません。これが実動コードである場合は、助けを求めることを検討してください。

于 2011-07-18T07:44:20.183 に答える
15

Advanced Encryption Standardから:

この規格は、AES-128、AES-192、およびAES-256の3つのブロック暗号で構成されており、元々Rijndaelとして公開されていたより大きなコレクションから採用されています。これらの各暗号のブロックサイズは128ビットで、キーサイズはそれぞれ128、192、256ビットです。

(強調追加)

初期化ベクトルから:

ブロック暗号動作モードの場合、IVは通常暗号のブロックサイズと同じ大きさです

これらの2つの要素を組み合わせると、キーサイズに関係なく、AESのIVは常に128ビットであることがわかります。

于 2011-07-18T07:41:29.600 に答える
2

ここでのAESはおそらくAES-256ではなくAES-128です。AES-256を有効にする場合は、エクスポート制御ポリシーが設定されているため、追加のjarを含める必要があります。したがって、最初にそれを確認してください。ほとんどの場合、AES-128で十分です。

IVは128ビットを超えることはできません。つまり、AES-128の場合は16バイトです。したがって、初期化ベクトルの長さを変更します。

それはうまくいくはずです。また、このhttp://en.wikipedia.org/wiki/Initialization_vectorをお読み ください

警告:IVを固定することは良い習慣ではありません。より良いセキュリティを提供するには、ランダムまたは疑似ランダムである必要があります。

于 2011-07-18T07:41:29.573 に答える
2

「マジックナンバー」を使用する代わりに、そのようなものを使用しないのはなぜですか。

SecureRandom random = new SecureRandom();
byte[] iv = random.generateSeed(16);

したがって、ivに対してランダムに16バイトを取得します。

于 2014-06-26T15:55:59.860 に答える
0

この問題が発生した理由は、IVを文字列として読み取り、それを間違った方法でバイト配列に変換していたためです。

正しい方法:

Hex.decodeHex(initializationVector.toCharArray()

を使用してorg.apache.commons.codec.binary.Hex

進入禁止:

initializationVector.getBytes()

これが間違っていた理由は、を呼び出すとgetBytes()、文字列を表すすべてのビットを取得し、それらをバイトにカットするためです。したがって、Unicodeテーブル0のインデックスを構成するビットとして書き込まれることになり0ます。これは0ではなく30であり、2バイトに書き込まれます。

逆に、ここで必要なのは、実際に0はバイトとして表されること00000000です。

于 2019-04-27T20:47:20.110 に答える
0

これとは関係ありませんが、同じ問題に直面しました。

IvParameterSpec ivParameterSpec = new IvParameterSpec(key1.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(key2.getBytes("UTF-8"),"AES"); 私が犯した間違いは、key1とkey2が16より大きい長さの文字列でした。長さを16に変更すると修正されました。

于 2022-01-07T08:46:33.200 に答える