2

I know this question has been asked several times but it doesn't seem to work with my code.

I'm getting an exception when decrypting:

"javax.crypto.BadPaddingException: pad block corrupted"

My code is:

private static byte[] appendIvToEncryptedData(byte[] eData, byte[] iv) throws Exception {
       ByteArrayOutputStream os = new ByteArrayOutputStream();
       os.write(eData);
       os.write(iv);
       return os.toByteArray();
    }

protected static byte[] dataEncryption(byte[] plainText)
    throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    byte [] iv = new byte[Constants.AES_BYTE_LENGTH];
    random.nextBytes(iv);
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    SecretKeySpec secretKeySpec = new SecretKeySpec(mAESKey, "AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, paramSpec);
    return appendIvToEncryptedData(cipher.doFinal(plainText), cipher.getIV());
}


protected static byte[] dataDecryption(byte[] encrypted)
    throws Exception {
    int ivIndex = encrypted.length - Constants.AES_BYTE_LENGTH;
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec secretKeySpec = new SecretKeySpec(mAESKey, "AES");
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, 
            new IvParameterSpec(encrypted, ivIndex, Constants.AES_BYTE_LENGTH));

    return cipher.doFinal(encrypted);
}

The exception is thrown when calling cipher.doFinal() in the dataDecryption() function. Besides, calling SecureRandom got this warning: "Potentially insecure random numbers on Android 4.3 and older. Read https://android-developers.blogspot.com/2013/08/some- securerandom-thoughts.html for more info."

I'm reading and writing files using RandomAccessFile and FileOutputStream so I'm working directly with byte arrays.

I've taken a look at this other question and modifyed my code as it says but still doesn't work:

Encryption error on Android 4.2

By the way, I'm encrypting in one device and decrypting in another different.

This is my stack trace:

11-01 20:57:14.820: I/Exception(26336): javax.crypto.BadPaddingException: pad block corrupted
11-01 20:57:14.820: I/Exception(26336):     at com.android.org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:701)
11-01 20:57:14.820: I/Exception(26336):     at javax.crypto.Cipher.doFinal(Cipher.java:1106)
11-01 20:57:14.820: I/Exception(26336):     at com.example.example.KeyManagement.dataDecryption(KeyManagement.java:132)
11-01 20:57:14.820: I/Exception(26336):     at com.example.example.SecureReceiving$1.onEvent(SecureReceiving.java:86)
11-01 20:57:14.820: I/Exception(26336):     at android.os.FileObserver$ObserverThread.onEvent(FileObserver.java:125)
11-01 20:57:14.820: I/Exception(26336):     at android.os.FileObserver$ObserverThread.observe(Native Method)
11-01 20:57:14.820: I/Exception(26336):     at android.os.FileObserver$ObserverThread.run(FileObserver.java:88)

Hope you can help me, thanks in advance.

Community
  • 1
  • 1
Fernando
  • 751
  • 2
  • 13
  • 27
  • Note: I would highly recommend using `new SecureRandom()` instead of using `getInstance()`, requiring a specific algorithm and provider. I would usually let the runtime system sort out which one is best. Also, you can use `cipher.getBlockSize()` instead of the constant. – Maarten Bodewes Nov 01 '14 at 21:14
  • I meant the constant used to define the size of the IV. Any luck with my answer? – Maarten Bodewes Nov 01 '14 at 22:08
  • It was all my bad, the code was working (well, i had to add the modification you mentioned below) but the problem (i think you mentioned it as well but i cannot find the comment) was that i was scanning the key (mAESKey) using a QR Code scanner but not storing it properly. I have a function called KeyManagement.setKey() and it turns out that because of my "copy/paste" habit, I was calling twice this function and in the end the key was wrong. Thanks a lot! – Fernando Nov 01 '14 at 23:03
  • 1
    Glad to have been of help. I removed the previous comment about the key after running the code locally (with a test key) and finding the culprit. I didn't expect that there would be two things amiss :) – Maarten Bodewes Nov 01 '14 at 23:22

1 Answers1

2

You've forgotten to remove the IV from the ciphertext.

Try:

return cipher.doFinal(encrypted, 0, ivIndex);

instead of

return cipher.doFinal(encrypted);

within the dataDecryption method.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263