Cipher.init() required for each message?

浪尽此生 提交于 2019-12-20 20:29:13

问题


Assume two clients are exchanging secure messages back and forth.

Must this block be run every time for each message, or can any step(s) be done just once at start:

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

I guess to lend some context- although I don't (yet) understand the internals completely, it is my understanding that for security purposes it's important to change the IV for each message. So I think the answer to this question will depend on whether that step happens under the hood at the doFinal() stage or init()....?


回答1:


You are correct: to be safe you need to use a new,random, IV for each message. This means you either need to recreate the cipher or randomly set the IV yourself for each subsequent message. The former is probably safer since if you change ciphers or modes, there maybe some other state you need to randomly set as well and reinitializing the cipher should handle all of it.

If you don't do this, you end up with the same rather bad bug SSL had with IV reuse.

Cipher.doFinal does not reset the cipher to a random IV. In fact, its far worse than that, it appears to reset the internal state to the same IV you started with. As shown by 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


来源:https://stackoverflow.com/questions/13071489/cipher-init-required-for-each-message

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!