Need a solution for the wrong IV length in AES

I am 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 testing, 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 AES implementation? Is there any way?

+5
source share
5 answers

Firstly,

 byte[] iv = {00000000000000000000000000000000}; 

creates an array of bytes of size 1, not an array of bytes of size 32 (if that is your intention).

Secondly, the size of the IV AES should be 16 or 128 bits (this is the size of the AES-128 block). If you are using AES-256, the IV size should be 128 bits large, since the AES standard only allows 128-bit block sizes. The original Rijndael algorithm allowed for other block sizes, including a 256-bit block size.

Thirdly, if you are going to use AES-256, this does not fail. You need to download and install the JCE Unlimited Strength Jurisdiction Policy Files (scroll to the bottom of the page); I also recommend reading the attached license.

This will 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 must be unique and unpredictable. A sequence of 16 bytes with each byte represented by a value of 0 is not a suitable candidate for IV. If this is production code, try getting help.

+38
source

From Advanced Encryption Standard :

The standard consists of 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 the Initialization Vector :

For block cipher mode of operation, IV usually has the size of the encryption block

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

+14
source

AES here is probably AES-128, not AES-256. You must enable the optional jar if you want to enable AES-256, as there are export management policies. So check this out first. AES-128 in most cases is enough.

Your IV cannot be more than 128 bits, i.e. 16 bytes if it is AES-128. So change the length of the initialization vector.

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

Warning. Fixed IV is not recommended. It must be random or pseudo-random in order to provide better security.

+2
source

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

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

So you get 16 random bytes for your iv.

+2
source

The reason I had this problem was because I read IV as a string and incorrectly converted it to a byte array.

Right:

 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 the bits that represent the string and splits them into bytes. Thus, 0 ends with writing in the form of bits making up the index 0 in the Unicode table, which is not 0, but 30, and which will be written in 2 bytes.

Conversely, here you actually want 0 be represented as byte 00000000 .

0
source

All Articles