Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating random IV for AES in Java

I'm implementing and AES encryption engine for PBE in android, and I've found two ways to implement the creation of the IV and I would like to know which one is better and more secure for getting IvParameterSpec:

Method #1:

SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);

IvParameterSpec ivParams = new IvParameterSpec(iv);

Method #2:

AlgorithmParameters params = cipher.getParameters();
byte[] iv2 = params.getParameterSpec(IvParameterSpec.class).getIV();

ivParams = new IvParameterSpec(iv2);
like image 589
user1576396 Avatar asked Mar 25 '15 22:03

user1576396


People also ask

How do you generate random IV of AES?

To generate the IV, we use the SecureRandom class. The block size required depends on the AES encryption block size. For the default block size of 128 bits, we need an initialization vector of 16 bytes. From the initialization vector, we create an IvParameterSpec which is required when creating the Cipher.

When implementing AES with Java What is an IV?

AES encryption best practice 1.1 The IV (initial value or initial vector), it is random bytes, typically 12 bytes or 16 bytes. In Java, we can use SecureRandom to generate the random IV. 1.2 The AES secret key, either AES-128 or AES-256 . In Java, we can use KeyGenerator to generate the AES secret key.

What is the use of IV in AES encryption?

The use of an IV prevents repetition in data encryption, making it more difficult for a hacker using a dictionary attack to find patterns and break a cipher. For example, a sequence might appear twice or more within the body of a message.

Does AES CBC use IV?

It works because Java picks a random IV.


1 Answers

I'd use method #1, because the Java API specifies the following for the Cipher.init() API that just takes the encryption/decryption mode and key:

If this cipher instance needs any algorithm parameters or random values that the specified key can not provide, the underlying implementation of this cipher is supposed to generate the required parameters (using its provider or random values).

(emphasis mine).

So it is not clear what different providers will do when method 2 is chosen. Looking at the Android source code, it seems that at least some versions (including version 21?) will not create a random IV - the random IV creation seems commented out.

Method 1 is also more transparent and it is - in my opinion - easier on the eyes.


Note that it is generally better to use new SecureRandom() and let the system figure out which RNG is best. "SHA1PRNG" is not well defined, may differ across implementations and is known to have had implementation weaknesses, especially on Android.


So the end result should be something like:

SecureRandom randomSecureRandom = new SecureRandom();
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);

Beware that GCM mode works best with a 12 byte IV instead of the 16 byte IV - the block size of AES.

like image 151
Maarten Bodewes Avatar answered Oct 02 '22 02:10

Maarten Bodewes