Jos*_*ree 0 java encryption aes
我试图内联我的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();
}
}
Run Code Online (Sandbox Code Playgroud)
这里
并输出:
ITERATION 1 IV pre rand:[0,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]
解密: 你好hello你好
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]
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]
解密: 你好hello你好
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]
解密: 你好hello你好
如果你看一下维基百科中有关CBC如何工作的精彩图片,你会看到通过将IV置于CBC明文的开头,你实际上取消了IV并破坏了它旨在提供的语义安全性.具体来说,使用CBC加密可以:
使用第一个明文块对IV进行异或,并将其加密到第一个密文块.由于您将第一个明文块作为IV的副本,因此它始终会对零块进行加密,并且每次都会产生相同的结果.
将第一个密文块与第二个明文块进行异或(这里是你搞砸之前的实际明文)并将其加密到第二个密文块.由于您将第一个密文块设为固定值,并且在测试中实际明文是相同的,因此每次都会产生相同的结果.
等等
做你应该做的事:
用(秘密)密钥和(随机)IV 加密实际明文,然后将IV与密文结合起来进行传输 ; 连接是一种简单的方法,但不是唯一的方法
在接收中将IV与密文分开或分开,并用(秘密)密钥和(随机但可见)IV解密密文