每个消息都需要Cipher.init()吗?
假设两个客户端来回交换安全消息。
每个消息的每次都必须运行此块,还是可以在开始时只执行一次任何步骤:
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
output = cipher.doFinal(content);
我想借给一些背景 - 虽然我还没有完全理解内部,但我的理解是,为了安全起见,改变每条消息的IV是很重要的。 所以我认为这个问题的答案将取决于该步骤是否发生在doFinal()阶段或init()....的底层。
你是对的:为了安全起见,你需要为每条消息使用一个新的随机IV。 这意味着您需要重新创建密码或为每个后续消息随机设置IV。 前者可能更安全,因为如果你改变了密码或模式,那么你可能需要随机设置一些其他状态,重新初始化密码应该处理所有这些状态。
如果你不这样做,你会得到与SSL重用相同的相当糟糕的错误。
Cipher.doFinal不会将密码重置为随机IV。 事实上,它远比这更糟糕,它似乎将内部状态重置为与您开始的IV相同的状态。 如此代码所示。
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
链接地址: http://www.djcxy.com/p/11359.html