Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid Decryption: Last block (16 bytes) is missing in result file
    primarykey
    data
    text
    <p>I'm currently working on a decryption algorithm to decrypt a PDF I'm receiving from the server for an eBook reader app. There is equivalent code which runs on iOS which works perfectly, I'm now trying to make the code run on Android.</p> <p>Just some details, the decryption is AES and runs in ECB mode. The encryption key is a hex string array which I convert into a byte array (by converting every two chars into a byte, eg: "FF" becomes 255, etc).</p> <p>What I'm experiencing is very interesting. I'm comparing the result files after decryption from both iOS and Android, and I'm noticing that consistently, the Android decryption files are 16 bytes shorter than the iOS decryption files, specifically in the end. All other bytes are identical (I will post below some examples).</p> <p>This difference is causing my eBook reader to refuse to open the PDFs, while it successfully opens the iOS books.</p> <p>Here is my decryption code:</p> <pre><code>private void performDecryption(DocumentModel document) { byte[] keyBytes = generateByteArray(document.getEncryptionKey()); SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES"); File encryptedDocument = new File(getBookFolderDocumentName(document, document.getFileSuffix())); File decryptedDocument = new File(BOOK_FOLDER + document.getGeneratedAssetName() + "_decrypted" + "." + document.getFileSuffix()); decryptedDocument.mkdirs(); if (decryptedDocument.exists()) decryptedDocument.delete(); Cipher cipher = null; try { cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); } catch (NoSuchAlgorithmException noSuchAlgorithmEx) { Log.e("Decryption", "NoSuchAlgorithmException: " + noSuchAlgorithmEx.getMessage()); } catch (NoSuchPaddingException noSuchPaddingEx) { Log.e("Decryption", "NoSuchPaddingException: " + noSuchPaddingEx.getMessage()); } catch (InvalidKeyException invalidKeyEx) { Log.e("Decryption", "InvalidKeyException: " + invalidKeyEx.getMessage()); } FileInputStream encryptedFileStream = null; FileOutputStream decryptedFileStream = null; try { encryptedFileStream = new FileInputStream(encryptedDocument); decryptedFileStream = new FileOutputStream(decryptedDocument); long totalFileSize = encryptedDocument.length(); long totalDecrypted = 0; int lastPercentage = -1; int currentPercentage = 0; byte[] encryptedBuffer = new byte[4096]; byte[] decryptedBuffer = new byte[4096]; int encryptedLength = 0; int decryptedLength = 0; while((encryptedLength = encryptedFileStream.read(encryptedBuffer)) &gt; 0) { while (encryptedLength % 16 != 0) // the code never lands in this loop { encryptedBuffer[encryptedLength] = 0; encryptedLength++; } decryptedLength = cipher.update(encryptedBuffer, 0, encryptedLength, decryptedBuffer); while (decryptedLength % 16 != 0) // the code never lands in this loop { decryptedBuffer[decryptedLength] = 0; decryptedLength++; } decryptedFileStream.write(decryptedBuffer, 0, decryptedLength); totalDecrypted += encryptedLength; currentPercentage = (int)(((float)totalDecrypted / (float)totalFileSize) * 100f); if (currentPercentage != lastPercentage) { lastPercentage = currentPercentage; Log.i("Decryption", "Decrypting... " + currentPercentage + "%"); } } Log.i("Decryption", "Finished decrypting!"); } catch (FileNotFoundException fileNotFoundEx) { Log.e("Decryption", "FileNotFoundException: " + fileNotFoundEx.getMessage()); } catch (IOException ioEx) { Log.e("Decryption", "IOException: " + ioEx.getMessage()); } catch (ShortBufferException e) { e.printStackTrace(); } finally { } try { encryptedFileStream.close(); decryptedFileStream.close(); cipherOutputStream.close(); } catch (IOException e1) { } document.setDecryptedFilePath(decryptedDocument.getAbsolutePath()); Log.i("Decryption", "Finished!"); } </code></pre> <p>Here are some samples from the pdf files (I used a hex reader to get these results):</p> <p>Book 1 (iOS): </p> <pre><code>0D 0A 3C 3C 2F 53 69 7A 65 20 35 38 31 3E 3E 0D 0A 73 74 61 72 74 78 72 65 66 0D 0A 31 31 36 0D 0A 25 25 45 4F 46 0D 0A 08 08 08 08 08 08 08 08 &lt;-- this block is missing in android. </code></pre> <p>Book 1 (Android):</p> <pre><code>0D 0A 3C 3C 2F 53 69 7A 65 20 35 38 31 3E 3E 0D 0A 73 74 61 72 74 78 72 65 66 0D 0A 31 31 36 0D </code></pre> <p>Book 2 (iOS):</p> <pre><code>65 6E 64 6F 62 6A 0D 73 74 61 72 74 78 72 65 66 0D 0A 34 30 36 32 35 33 36 0D 0A 25 25 45 4F 46 0D 0A 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E &lt;-- this block is missing in android. </code></pre> <p>Book 2 (Android):</p> <pre><code>65 6E 64 6F 62 6A 0D 73 74 61 72 74 78 72 65 66 0D 0A 34 30 36 32 35 33 36 0D 0A 25 25 45 4F 46 </code></pre> <p>What I'm noticing is that the last bytes have several identical bytes at the end, equal to the amount of times they appear. In book 1 iOS, in the last block, the byte 08 appears exactly 8 times. In book 2 iOS, in the last block, the byte 0e (14) appears exactly 14 times, etc.</p> <p>Other than that, I'm not sure what pattern is occurring, so I'm not sure how I can solve this.</p> <p>I've already tried using the following different padding types:</p> <pre><code>ZeroBytePadding, NoPadding, PKCS5Padding, PKCS7Padding </code></pre> <p>Any ideas would be greatly appreciated.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload