每个消息都需要Cipher.init()? [英] Cipher.init() required for each message?

查看:308
本文介绍了每个消息都需要Cipher.init()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设两个客户端正在交换安全邮件。

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);

我想借出一些上下文 - 虽然我还没有完全理解内部是我的理解,为安全目的,重要的是改变每个消息的IV。所以我认为这个问题的答案将取决于这个步骤发生在doFinal()阶段或init()....下。

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()....?

推荐答案

您是正确的:为了安全起见,您需要为每封邮件使用新的随机IV。这意味着你需要重新创建密码或随机设置IV自己为每个后续的消息。前者可能更安全,因为如果你改变密码或模式,可能还有一些其他状态你需要随机设置以及重新初始化密码应该处理所有它。

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.

如果你不这样做,你最终得到的SSL与第四代相同的错误bug 重用

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

Cipher.doFinal不会将密码重置为随机IV。事实上,它远远差于它,似乎将内部状态重置为您开始的同一个IV。如此代码所示。

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

这篇关于每个消息都需要Cipher.init()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆