0

I would like to implement this code which is, AES encryption in CBC mode with an inline IV, but there is this error message:

Wrong IV length: must be 16 bytes long

and the code is:

package implementaes;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec;

public class Aesaesaes
{
    public static void main(String[] args)
    {
        try
        {
                //Lookup a key generator for the AES cipher
                        KeyGenerator kg = KeyGenerator.getInstance("AES");
            SecretKey key = kg.generateKey();

            SecretKeySpec keySpec = new
                        SecretKeySpec(key.getEncoded(), "AES");     
                //Lookup an instance of a AES cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

                //initialize IV  manually

                byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

                //create IvParameterSpecobject

                IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);     

               //Initialize the cipher using the secter key

            cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivSpec);

                String plainText = "This is a secret!";



            byte[] cipherText = cipher.doFinal(plainText.getBytes());

            System.out.println("Resulting Cipher Text:\n");
            for(int i=0;i<cipherText.length;i++)
            {
                System.out.print(cipherText[i] + " ");
            }
            System.out.println("");



        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

How can I sort it out? By the way I tried:

byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00};

to be 16 Byte, but does not work

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
nana
  • 59
  • 8

1 Answers1

0

The ivBytes that you are defining is currently 8 bytes:

byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

Each member in the ivBytes array represents one byte. You need an array of 16 entries:

byte[] ivBytes = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  

UPDATE I thought it was obvious that you were going to supply your own values to the IV but it's probably worth it to point you to Dave's comment that it's in your best interest to not initialize the IV to all zeros. See how to pick an IV

Community
  • 1
  • 1
Tung
  • 5,334
  • 1
  • 34
  • 41
  • Each cell is only 8 bits wide. 0x00 is 0, and 0 fits in those 8 bits. The fact that you've chosen to represent the 0 as 0x00 in java will not change the width of each cell in the array. – Tung Apr 20 '16 at 13:38
  • Or for zeros just do `= new byte[16];` -- that form allocates the specified size with all elements zero (or null if an object array). @Tung Note that using a constant IV, including zeros, is often insecure depending on what the encryption is used for; the whole reason the IV exists for CBC is to be unique and unpredictable. OTOH you've thrown away the key, so you've actually made it as hard for the legitimate recipient as for the adversary. – dave_thompson_085 Apr 20 '16 at 14:26
  • @dave_thompson the values in the answer are only there for demonstrative purposes (any other suggested value may have thrown off the OP, but it's good that you clarified this for them). – Tung Apr 20 '16 at 16:29