Is there any difference if I initialize the AES cipher, with and without IvParameterSpec

I was wondering if there is any difference if I initialize the AES cipher, with and without IvParameterSpec?

With IvParameterSpec

SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16])); 

Without IvParameterSpec

 SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 

I tested several test data, their encryption and decryption result gives the same thing.

However, since I am not a security expert, I do not want to miss anything and create a potential security hole. I was wondering what is the correct way?

+5
source share
2 answers

A bit of background (sorry if you already know this, just make sure we use the same terminology):

  • AES is a block cipher, an encryption algorithm that works with 128-bit blocks.
  • CBC is a block cipher mode, a way to use block cipher to encrypt large amounts of data.
  • For block encryption modes, an initialization vector (IV) is needed, which is a block of initialization data, usually the same size as the size of the block underlying the encryption.

(The Wikipedia about block encryption modes - http://en.wikipedia.org/wiki/Block_cipher_mode - is really good, and makes it clear why you need IV.)

Different block modes present different requirements for the IV selection process, but they all have one thing in common:

You should never encrypt two different messages with the same IV and key. If you do this, an attacker can get your plaintext, and sometimes your key (or equivalently useful data).

CBC imposes an additional restriction that IV must be unpredictable for an attacker - therefore, artjom-b's SecureRandom to use SecureRandom to create it is a good one.


Also, as artjob-b points out, CBC gives you privacy. In practice, this means that your data is kept secret, but there is no guarantee that it will arrive in one piece. Ideally, you should use authenticated mode such as GCM, CCM, or EAX.

Using one of these modes is really, really a good idea . Encrypt-then-MAC is cumbersome even for experts; Avoid this if you can. (If you need to do this, remember that you must use different keys for encryption and MAC.)

+7
source

If IvParameterSpec is not provided, Cipher should initialize the random IV itself, but it seems that in your case it does not ( new byte[16] is an array filled with 0x00 bytes). The Cipher implementation seems to be broken. In this case, you should always provide a new random IV (necessary for semantic security).

This is usually done as follows:

 SecureRandom r = new SecureRandom(); // should be the best PRNG byte[] iv = new byte[16]; r.nextBytes(iv); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(iv)); 

When you send or save encrypted text, you must add it to it. During decryption, you only need to cut off the IV from the encrypted text in order to use it. It does not need to be kept secret, but it must be unique.


Please note that only CBC mode gives you privacy. If any type of manipulation of encrypted texts (malicious or non-malicious) is possible, you should use authenticated mode, such as GCM or EAX. It will also provide you with integrity in addition to privacy. If you do not have access to those (they have SpongyCastle), you can use the message authentication code (MAC) in the encryption scheme and then the MAC, but it is much more difficult to implement correctly.

+3
source

All Articles