champskee
champskee

Reputation: 27

Trying to remove the last 16 bytes that I appended onto the byte[] (which is the IV) then decrypt

Here is my encryption class:

public static void encrypt(byte[] file, String password, String fileName, String dir) throws Exception {

    SecureRandom r = new SecureRandom();
    //128 bit IV generated for each file
    byte[] iv = new byte[IV_LENGTH];
    r.nextBytes(iv);
    IvParameterSpec ivspec = new IvParameterSpec(iv);
    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec);

    FileOutputStream fos = new FileOutputStream(dir + fileName);
    fos.write(iv);

    CipherOutputStream cos = new CipherOutputStream(fos, cipher);

    // Have to append IV --------

    cos.write(file);

    fos.flush();
    cos.flush();
    cos.close();
    fos.close();
}

This is my Decryption method:

public static void decrypt(byte[] file, String password, String fileName, String dir) throws Exception
{   
    // gets the IV
    int ivIndex = file.length - 16;

    byte[] truncatedFile = Arrays.copyOfRange(file, 0, file.length - 16);

    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(truncatedFile, ivIndex, 16));

    //IvParameterSpec ivspec = new IvParameterSpec(iv);
    //
    //cipher.init(Cipher.DECRYPT_MODE, keySpec, ivspec);

    FileOutputStream fos = new FileOutputStream(dir + fileName);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);

    cos.write(file);
    fos.flush();
    cos.flush();
    cos.close();
    fos.close();
}

}

As you can see I generated a 16 byte long IV that I have appended to the end of the encrypted file. This is so that I pull off the IV for decryption as well as every filing have a unique IV. I am currently getting the error:

java.lang.IllegalArgumentException: IV buffer too short for given offset/length combination

Aside from the problem generating the error, is my logic correct? will this work?

Upvotes: 1

Views: 794

Answers (1)

user207421
user207421

Reputation: 310985

I generated a 16 byte long IV that I have appended to the end of the encrypted file.

No you didn't. You pre-pended it. Which is a better idea anyway. So you have to read it first, and then construct your Cipher and CipherInputStream and decrypt the remainder of the file input stream. You don't need to read the entire file into memory to accomplish that:

public static void decrypt(File file, String password) throws Exception
{
    byte[] iv = new byte[16];
    DataInputStream dis = new DataInputStream(new FileInputStream(file));
    dis.readFully(iv);

    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
    CipherInputStream cis = new CipherInputStream(dis, cipher);

    // Now just read plaintext from `cis` and do whatever you want with it.

    cis.close();
}

Upvotes: 5

Related Questions