I was wondering, is there any difference, if I init AES cipher, with and without 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]));
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?
A bit of background (I'm sorry if you already know this, it's just worth making sure we're using the same terminology):
(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.)