Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I was wondering, is there any difference, if I init 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 with some sample test data, their encryption and decryption result yield the same.

However, since I'm not the security expert, I don't want to miss out anything, and create a potential security loop hole. I was wondering, which is the correct way?

like image 328
Cheok Yan Cheng Avatar asked Apr 11 '15 06:04

Cheok Yan Cheng


People also ask

What is the use of IvParameterSpec?

Class IvParameterSpec. This class specifies an initialization vector (IV). Examples which use IVs are ciphers in feedback mode, e.g., DES in CBC mode and RSA ciphers with OAEP encoding operation.

Which AES mode should I use?

XTS mode is the most common if you are encoding a random accessible data (like a hard disk or RAM). OCB is by far the best mode, as it allows encryption and authentication in a single pass.

Is IV necessary for AES encryption?

AES algorithm requires two different parameters for encryption, a key and an initialization vector (IV).

Does AES need salt?

AES doesn't have a concept of a salt. It just takes data, and a key. For the same input, it will always generate the same output. How you combine your message with your salt is up to you.


2 Answers

A bit of background (I'm sorry if you already know this, it's just worth making sure we're using the same terminology):

  • AES is a block cipher, an encryption algorithm that operates on 128-bit blocks.
  • CBC is a block cipher mode, a way of using a block cipher to encrypt large amounts of data.
  • Block cipher modes need an initialisation vector (IV), which is a block of initialisation data, usually the same size as the block size of the underlying cipher.

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

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

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

CBC imposes an additional constraint, which is that the IV must be unpredictable to an attacker - so artjom-b's suggestion of using a SecureRandom to generate it is a good one.


Additionally, as artjob-b points out, CBC only gives you confidentiality. What that means in practice is that your data is kept secret, but there's no guarantee that it arrives in one piece. Ideally, you should use an authenticated mode, such as GCM, CCM, or EAX.

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

like image 120
Justin King-Lacroix Avatar answered Sep 20 '22 18:09

Justin King-Lacroix


When no IvParameterSpec is provided then the Cipher should initialize a random IV itself, but it seems that in your case, it doesn't do this (new byte[16] is an array filled with 0x00 bytes). It seems the Cipher implementation is broken. In that case you should always provide a new random IV (necessary for semantic security).

This is usually done this way:

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 then send or store the ciphertext, you should prepend the IV to it. During decryption you only need to slice the IV off the front of the ciphertext to use it. It doesn't need to be kept secret, but it should be unique.


Note that CBC mode alone only gives you confidentiality. If any type of manipulation of ciphertexts (malicious or non-malicious) is possible then you should use an authenticated mode like GCM or EAX. Those will also give you integrity in addition to confidentiality. If you don't have access to those (SpongyCastle has them), you could use a message authentication code (MAC) in an encrypt-then-MAC scheme, but it is much harder to implement correctly.

like image 44
Artjom B. Avatar answered Sep 20 '22 18:09

Artjom B.