我正在尝试内联我的IV,这样我就可以在不知道初始IV,只知道密钥的情况下解密我的消息。
我生成了我的钥匙。 我使用SecureRandom生成我的IV 我对IV字节数组进行了randominze。 (我用iv +消息创建一条消息) 最后,我使用独特的IV加密消息。
正如预期的那样,如果我在接收端删除IV,我可以解密该消息。 但是,生成的密文始终相同。
我不知道为什么会这样,并且还没有在线找到解决方案。
以下是我的代码和输出。
任何人都可以帮助我理解为什么会这样吗?
enter code
String mssg = "Hello hellow hello";
byte[] key = "kljhn1234512345abcde123451234512".getBytes();
SecretKeySpec spec = new SecretKeySpec(key, "AES");
SecureRandom rand = new SecureRandom();
for (int i = 0; i < 5; i++) {
//
//initialzize empty byte array for random IV
byte[] iv = new byte[16];
System.out.println("IV pre rand: " + Arrays.toString(iv));
rand.nextBytes(iv); //RANDOMIZE
System.out.println("IV POST rand: " + Arrays.toString(iv));
//CONCATENTATE IV TO FRONT OF MESSAGE TO ENCRYPT
//CONCATENATE MESSAGE TO END OF IV
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
bout.write(iv);
bout.write(mssg.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
byte[] message = bout.toByteArray();
try {
//ENCRYPT USING RANDIMIZED IV.. THIS SHOULD RESULT IN NON EQUAL CIPHER TEXT FOR SAME MESSAGE.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, spec, new IvParameterSpec(iv));
byte[] ct = cipher.doFinal(message);
System.out.println("CIPHER TEXT: " + Arrays.toString(ct));
//DECRYPT. AND USING A WRONG IV.
cipher.init(Cipher.DECRYPT_MODE, spec, new IvParameterSpec(new byte[16]));
System.out.println("DECRYPTED: " + new String(cipher.doFinal(ct)));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
这里
输出:
ITERATION 1 IV pre rand:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
IV POST rand:[13,68,83,113,86,48,50,-71,-75,-25,56,100,-25,34,-27,-23]
CIPHER TEXT:[ - 102,-52,-21,-92,-85,119,-10,-18,-52,0,-39,-19,11,-83,70,44, 101,-92,-93,-60,4,73,-17,73,-58,119,81,66,-114,54,-107,-83,11,42,-92,121, - 15,-61,92,83,24,10,89,-21,110,100,116,119]
解密:��������������������������������你好hellow你好
ITERATION 2: IV pre rand:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
IV POST rand:[90,115,91,124,27,-80,-32,-46,-66,-50,-85,43,34,-18,-74,-3] < / p>
CIPHER TEXT:[ - 102,-52,-21,-92,-85,119,-10,-18,-52,0,-39,-19,11,-83,70,44, 101,-92,-93,-60,4,73,-17,73,-58,119,81,66,-114,54,-107,-83,11,42,-92,121, - 15,-61,92,83,24,10,89,-21,110,100,116,119]
解密:��������������������������������你好hellow你好
ITERATION 3
IV pre rand:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
IV POST rand:[113,112,9,47,-125,-4,80,10,-97,44,42,90,-58,-44,-46,17]
CIPHER TEXT:[ - 102,-52,-21,-92,-85,119,-10,-18,-52,0,-39,-19,11,-83,70,44, 101,-92,-93,-60,4,73,-17,73,-58,119,81,66,-114,54,-107,-83,11,42,-92,121, - 15,-61,92,83,24,10,89,-21,110,100,116,119]
解密:��������������������������������你好hellow你好
答案 0 :(得分:5)
如果您查看the nice picture in Wikipedia of how CBC works,您会看到通过将IV放在CBC明文的开头,您实际上取消了IV并破坏了它打算提供的语义安全性。具体来说,使用CBC进行加密可以:
使用第一个明文块对IV进行异或,并将其加密到第一个密文块。由于您将第一个明文块作为IV的副本,因此它总是加密零块并且每次都产生相同的结果。
将第一个密文块与第二个明文块进行异或(这里是你搞砸之前的实际明文)并将其加密到第二个密文块。由于您将第一个密文块设为固定值,并且在测试中实际明文是相同的,因此每次都会产生相同的结果。
等等。
做你应该做的事情:
使用(秘密)密钥和(随机)IV加密实际明文,然后将IV与密文组合用于传输< / em>的;连接是一种简单的方法,但不是唯一的方法
将IV与密文分开或分开,并用(秘密)密钥和(随机但可见的)IV解密密文