0

While encrypting and decrypting a file using CipherInputStream and CipherOutputStream, the decrypted file is different from the original. There are no errors thrown when during execution, but the original and the result have different hashes. The original and the result are also the exact same size. There is not any file collisions/overwriting going on. My best guess so far is character encoding.

public void fileTest(File source, File output, String key) throws Exception { Log.write("Starting file encryption/decryption test!"); Util.charset = CharsetToolkit.guessEncoding(source, 4096, StandardCharsets.UTF_8); Log.write("Using charset " + Util.charset.name()); Log.write("Using key: " + key); String oHash = Util.checksum(source); Log.write("Original hash: " + oHash); //Cipher setup SecretKeySpec sks = Util.padKey(key); Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); Cipher dCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); eCipher.init(Cipher.ENCRYPT_MODE, sks, new IvParameterSpec(new byte[16])); dCipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(new byte[16])); //IO setup File tmpEncrypt = new File(source.getParent() + "/" + source.getName() + "-tmp"); tmpEncrypt.createNewFile(); output.createNewFile(); Log.write("Encrypting to: " + tmpEncrypt.getAbsolutePath()); InputStream fis = new FileInputStream(source); InputStream enIn = new FileInputStream(tmpEncrypt); OutputStream fos = new FileOutputStream(tmpEncrypt); OutputStream clearOut = new FileOutputStream(output); CipherInputStream cis = new CipherInputStream(enIn, dCipher); CipherOutputStream cos = new CipherOutputStream(fos, eCipher); //Encrypt Log.write("Starting encryption process"); int numRead = 0; byte[] buffer = new byte[1024]; while ((numRead = fis.read(buffer)) >= 0) { cos.write(buffer, 0, numRead); } cos.close(); fos.close(); Log.write("Done!"); Log.write("Encrypted hash: " + Util.checksum(output)); //Decrypt Log.write("Starting decryption process"); int nr = 0; byte[] b = new byte[1024]; while ((nr = cis.read(b)) >= 0) { clearOut.write(buffer, 0, nr); } clearOut.close(); cis.close(); fis.close(); Log.write("Done!"); String fHash = Util.checksum(output); Log.write("Final hash: " + fHash); if(fHash.equals(oHash)) { Log.write("Success! The hashes are equal!"); } else { Log.write("Failure! Hashes are different!"); } } 

EDIT: I took your advice @zaph, and now it seems to be a problem with writing/read the file. The file is exactly 40 bytes long. Here's the hex dumps:

Key hex: 000074657374696e676b65797364617767313233 IV hex: 0000000000000000000000000000000000000000 Data IN: Lorem ipsum dolor sit amet orci aliquam. Data OUT: Lorem ipsum dolor sit amet orci Lorem ip. 

Odd, it seems to be overwriting the last 8 bytes with a repetition of the first 8 bytes. I tried adjusting my buffer size from 1024 bytes down to 8 bytes, and it got even stranger. Hex dump from 8 byte test:

Key hex: 000074657374696e676b65797364617767313233 IV hex: 0000000000000000000000000000000000000000 Data IN: Lorem ipsum dolor sit amet orci aliquam. Data OUT: aliquam.aliquam.aliquam.aliquam.aliquam. 

Something is definitely wrong with the way the first is being read/wrote, but I don't have a clue what is going on. Thank you in advance!

3
  • Have you made a diff between the original and the decrypted file? Please note the the first hash is not of the original file, but rather an empty target file. Commented Jun 2, 2016 at 16:48
  • Create a minimal test case, a short file, perhaps 40 bytes in length. Hex dump the key, iv and data in and out for both the encryption and decryption. Compare for discrepancies. Add all that to the question if you can't find the problem. Commented Jun 2, 2016 at 16:52
  • I have updated the question, thanks for the help so far. Commented Jun 2, 2016 at 18:27

1 Answer 1

2

Solved it! There was a problem with my while loops. Like this one:

while ((nr = cis.read(b)) >= 0) { clearOut.write(buffer, 0, nr); } 

So I replaced it with a for loop instead and everything is working.

int segs = (int) (source.length() / 4); for (int i = 0; i < segs; i++) { fis.read(buffer); cos.write(buffer, 0, buffer.length); } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.