带有内联安全随机IV的Java AES CBC - 生成相同的密文?

时间:2016-10-14 19:22:00

标签: 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();
            }


        }

这里

输出:

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你好

1 个答案:

答案 0 :(得分:5)

如果您查看the nice picture in Wikipedia of how CBC works,您会看到通过将IV放在CBC明文的开头,您实际上取消了IV并破坏了它打算提供的语义安全性。具体来说,使用CBC进行加密可以:

  • 使用第一个明文块对IV进行异或,并将其加密到第一个密文块。由于您将第一个明文块作为IV的副本,因此它总是加密零块并且每次都产生相同的结果。

  • 将第一个密文块与第二个明文块进行异或(这里是你搞砸之前的实际明文)并将其加密到第二个密文块。由于您将第一个密文块设为固定值,并且在测试中实际明文是相同的,因此每次都会产生相同的结果。

  • 等等。

做你应该做的事情:

  • 使用(秘密)密钥和(随机)IV加密实际明文,然后将IV与密文组合用于传输< / em>的;连接是一种简单的方法,但不是唯一的方法

  • 接收上的
  • 将IV与密文分开或分开,并用(秘密)密钥和(随机但可见的)IV解密密文