Need solution for wrong IV length in AES

流过昼夜 提交于 2020-01-09 09:16:25

问题


I'm trying to implement AES in Java and this is the code I use:

 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);

I need this fixed key and IV for test purpose but I get the following exception:

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)

How can I use this fixed IV with this implementation of AES? Is there any way?


回答1:


Firstly,

byte[] iv = {00000000000000000000000000000000};

creates a byte array of size 1 and not a byte array of size 32 (if that is your intention).

Secondly, the IV size of AES should be 16 bytes or 128 bits (which is the block size of AES-128). If you use AES-256, the IV size should be 128 bits large, as the AES standard allows for 128 bit block sizes only. The original Rijndael algorithm allowed for other block sizes including the 256 bit long block size.

Thirdly, if you are intending to use a AES-256, this does not come out of the box. You need to download and install the JCE Unlimited Strength Jurisdiction Policy Files (scroll to the bottom of the page); I would also recommend reading the accompanying license.

This would result in the following change to your code:

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

Finally, the initialization vector is meant to be unique and unpredictable. A sequence of 16 bytes, with each byte represented by a value of 0, is not a suitable candidate for an IV. If this is production code, consider getting help.




回答2:


From Advanced Encryption Standard:

The standard comprises three block ciphers, AES-128, AES-192 and AES-256, adopted from a larger collection originally published as Rijndael. Each of these ciphers has a 128-bit block size, with key sizes of 128, 192 and 256 bits, respectively

(Emphasis added)

From Initialization Vector:

For block cipher modes of operation, the IV is usually as large as the block size of the cipher

Combine those two factors together, and you get that the IV is always 128 bits for AES, independent of the key size.




回答3:


Why not just use something like that instead of using "magic numbers":

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

So you get 16 random bytes for your iv.




回答4:


AES here is probably AES-128 not AES-256.You must include extra jar if you want to enable AES-256 as there are export control policies in place. So check that first. AES-128 is enough in most cases.

Your IV can't be more than 128 bits i.e. 16 bytes when it is AES-128. So change the initialization vector length.

That must work. Also, read this http://en.wikipedia.org/wiki/Initialization_vector

Warning: It is not a good practice to have a fixed IV. It must be random or pseudorandom to offer better security.




回答5:


The reason why I had this problem was because I was reading the IV as a String, and converting it to a byte array the wrong way.

Right way:

Hex.decodeHex(initializationVector.toCharArray()

using org.apache.commons.codec.binary.Hex

Wrong way:

initializationVector.getBytes()

The reason this was wrong, is because when you call getBytes(), it just takes all bits that represent the string and cuts them into bytes. So 0 ends up being written as the bits that make up the index of 0 in the Unicode table, which is not 0 but 30, and which would be written on 2 bytes.

Conversely, what you want here is actually that 0 be represented as the byte 00000000.



来源:https://stackoverflow.com/questions/6729834/need-solution-for-wrong-iv-length-in-aes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!