First I created a little encryption/decryption program in Java/Android. Nothing special about this just really basic, so no buffers or anything. Used an Iv and Salt there I write the salt and the iv at the beginning of the file(24 bytes) . This first version was able to en/decrypt a file and both files where binary the same in the end.
Now I tried to not read and process the whole file at once, but in single steps with a buffer (size 1024 bytes). I changed my cipher.doFinal
to multiple cipher.update and one empty cipher.doFinal
at the end.
Encryption:
byte[] salt = {1, 2, 3, 4, 5, 6, 7, 8};
byte[] iv = {23, 45, 23, 12 , 39, 111, 90, 1, 2, 3, 4, 5, 6, 7, 8, 9};
FileInputStream fis = new FileInputStream(f);
byte[] buffer = new byte[1024];
byte[] output = new byte[24];
cpyArray(iv, output, 0);
cpyArray(salt, output, 16);
FileOutputStream fos = new FileOutputStream(new File(f.getPath() + ".enc"));
fos.write(output);
Cipher cipher = getcCipher(pass, salt,iv, Cipher.ENCRYPT_MODE);
for(int length; (length = fis.read(buffer)) > 0; ) {
byte[] realbuffer = new byte[length];
if (length != 1024) {
cpyArrayUntil(buffer, realbuffer, 0, length);
} else {
realbuffer = buffer;
}
byte[] chipped = cipher.update(realbuffer)
fos.write(chipped);
System.out.println("Chipped: " + chipped.length);
}
cipher.doFinal();
fis.close();
fos.close();
Decryption:
Cipher cipher = getcCipher(pass, salt, iv, Cipher.DECRYPT_MODE);
byte[] buffer = new byte[1024];
for(int length; (length = fis.read(buffer)) > 0; ) {
byte[] realbuffer = new byte[length];
if (length != 1024) {
cpyArrayUntil(buffer, realbuffer, 0, length);
} else {
realbuffer = buffer;
}
byte[] chipped = cipher.update(realbuffer)
fos.write(chipped);
System.out.println("Chipped: " + chipped.length);
}
cipher.doFinal();
So, the problem is now, when I run this and compare the files at the end,
1. I get a BadPaddingExeption on the doFinal while decrypting.
and
2. The file that was En-and Decrypted is missing 29 bytes at the end of the file.
No worries, the Iv and the salt are normally random, just static for testing.
Also, the missing bytes depend on the filesize. Just tryed another file and it is missing 21 bytes.
You are discarding the output of doFinal()
in both your encrypt and decrypt routines. These both return a byte[]
which must also be written to your output in order for the encrypted ciphertext or decrypted plaintext to be complete and valid.