3

So I have these large files (6GB+) that I need to decrypt on a 32 bit computer. The general procedure that I used previously was to read the entire file in memory, then pass it on to the decrypt function and then write it all back to a file. This doesn't really work due to memory limitations. I did try passing the file in parts to the decrypt function but it seems to mess up around the boundaries of where I break up the file before sending it to the decrypt function.

I've tried breaking up the file in parts relative to key size but that doesnt seem to matter. I tried a byte array of size 2048 as well as a byte aray of size 294 thinking that might be the special boundary but, no luck. I can see parts of the file correctly decrypted but parts which are total gibberish.

Is it just NOT POSSIBLE to decrypt the file in chunks? If there is a way, then how?

Here is my decryption function / my attempt to decrypt in parts.

  private Path outFile;

  private void decryptFile(FileInputStream fis, byte[] initVector, byte[] aesKey, long used) {
    //Assume used = 0 for this function. 
    byte[] chunks = new byte[2048]; //If this number is greater than or equal to the size of the file then we are good.
    try {
      if (outFile.toFile().exists())
        outFile.toFile().delete();
      outFile.toFile().createNewFile();
      FileOutputStream fos = new FileOutputStream(outFile.toFile());
      OutputStreamWriter out = new OutputStreamWriter(fos);
      IvParameterSpec spec = new IvParameterSpec(Arrays.copyOfRange(initVector, 0, 16));
      SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
      Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
      cipher.init(Cipher.DECRYPT_MODE, key, spec);
      int x;
      while ((x = fis.read(chunks, 0, chunks.length)) != -1) {
        byte[] dec = cipher.doFinal(Arrays.copyOfRange(chunks, 0, x));
        out.append(new String(dec));
      }
      out.close();
      fos.close();
    } catch (Exception e) {
      e.printStackTrace();
      LOG.error(ExceptionUtils.getStackTrace(e));
    }
  }
Sanchit
  • 2,240
  • 4
  • 23
  • 34
  • This question might help http://stackoverflow.com/questions/11300128/encrypting-and-or-decrypting-large-files-aes-on-a-memory-and-storage-constrain – Ashay Thorat Sep 06 '13 at 07:16
  • 1
    It would probably make sense to only use `doFinal` on the last chunk. By default, you would make use of `update(byte[], int, int, byte[], int)` for multipart operations. This will take care of part boundaries for you. – Tadas S Sep 06 '13 at 07:32
  • Never thought about that >_< Let me check if there are other methods other than doFinal that I can use. – Sanchit Sep 06 '13 at 07:36

1 Answers1

4

Consider using Cipher#update(byte[], int, int, byte[], int) instead of doFinal() for multipart operations. This will take care of part boundaries for you.

The last part of the deciphered data can be obtained by calling the doFinal(byte[] output, int outputOffset) method.

Tadas S
  • 1,955
  • 19
  • 33