Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
877 views
in Technique[技术] by (71.8m points)

cryptography - 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);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...