Is Cipher.init () required for every post?

Suppose that two clients exchange secure messages back and forth.

Whether this block should be run every time for each message, or each step can be performed only once at startup:

cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); output = cipher.doFinal(content); 

I assume that I am providing some context, although I still do not fully understand the insides, I understand that for security purposes it is important to change the IV for each message. Therefore, I think that the answer to this question will depend on whether this step occurs under the hood at the stage of doFinal () or init () ....?

+7
source share
1 answer

You are right: to be safe, you need to use a new, random, IV for each message. This means that you need to either recreate the cipher, or arbitrarily set IV yourself for each subsequent message. The first one is probably more secure, because if you change the ciphers or modes, you probably need to set up some other state in a random order, and re-initializing the encryption should handle all this.

If you do not, you will have the same bad SSL bug with repeating IV.

Cipher.doFinal does not use reset cipher for random IV. In fact, it’s much worse than this, it seems, to reset the internal state to the same IV that you started with. As shown in this code.

  Cipher f = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); f.init(Cipher.ENCRYPT_MODE, key); byte[] iv = f.getIV(); System.out.println(Arrays.toString(f.doFinal("hello".getBytes()))); System.out.println(Arrays.toString(f.getIV())); System.out.println(Arrays.toString(f.doFinal("hello".getBytes()))); System.out.println(Arrays.toString(f.getIV())); System.out.println( Arrays.equals(f.getIV(), iv)); // true 
+3
source

All Articles