BadPaddingException Error: Block Block is Damaged

I am trying to decrypt a file in Java that has been encrypted in C # using Rijndael / CBC / PKCS7. I keep getting the following exception:

javax.crypto.BadPaddingException: blocking block is damaged
at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal (Unknown source)
on javax.crypto.Cipher.doFinal (DashoA13 * ..)
in AESFileDecrypter.decrypt (AESFileDecrypter.java:57)

when the doFinal(inpbytes) method is called by the web server for the first byte []. I assume this is a key or IV problem. I have encrypted files in my file system for testing. Is there something that anyone can see in my code below, right?

*** keyStr encoded in base64

 public AESFileDecrypter(String keyStr){ try { Security.addProvider(new BouncyCastleProvider()); convertIvParameter(); key = new sun.misc.BASE64Decoder().decodeBuffer(keyStr); //use the passed in Base64 decoded key to create a key object decryptKey = new SecretKeySpec(key, "AES"); //specify the encryption algorithm decryptCipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); //make a parameter object for the initialization vector(IV) IvParameterSpec ivs = new IvParameterSpec(_defaultIv); //initialize the decrypter to the correct mode, key used and IV decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey, ivs); } catch (Exception e) { e.printStackTrace(); } } public void convertIvParameter() { int[] iv = new int[] {11, 190, 165, 33, 68, 88, 11, 200, 245, 35, 68, 23, 60, 24, 223, 67}; _defaultIv = new byte[16]; for(int x = 0; x < _defaultIv.length; x++) { _defaultIv[x] = (byte)iv[x]; } } public void decryptUpdate(byte[] inpBytes) throws Exception { //decrypt the byte passed in from the web server decryptCipher.update(inpBytes); } public byte[] decryptFinal() throws Exception { //decrypt the byte passed in from the web server return decryptCipher.doFinal(); } //sends bytes to the client for diaply private void sendBytes(FileInputStream fis, OutputStream os)throws Exception { //set the buffer size to send 4k segments of data aesFileDecrypter = new AESFileDecrypter(<Insert Key string here>); byte[] buffer = new byte[4096]; int bytes = 0, totalBytes = fis.available(); //while there is still data to be sent keep looping and write the data //to the output stream as the buffer is filled try { while ((bytes = fis.read(buffer)) != -1) { aesFileDecrypter.decryptUpdate(buffer); //os.write(buffer, 0, bytes); } os.write(aesFileDecrypter.decryptFinal(), 0, totalBytes); } catch(Exception e) { e.printStackTrace(); } } 
+7
java exception encryption
source share
4 answers

First, just to be clear, from the comments below, you should not call doFinal () on each block, because doFinal () expects that there will be any addition at the end that will not be explicitly in the intermediate blocks. Either (a) call update () for the intermediate data, and then finalize final () at the end, or (b) just organize all your data in one buffer or byte array and call doFinal () once on the entire batch of jobs.

From the code you posted, it is not clear that this is actually what you are doing, but it should be mentioned just in case.

Otherwise, as a first step towards debugging, I would suggest which of these two options is easier for you:

  • Decryption in ECB mode without filling in and viewing what you get. Look at the first block of data that it returns. If you can use XOR with your IV bytes and receive the expected decrypted data, you know that your key is in order.
  • Flushing the actual key bytes from C # before base 64 and Java encoding after decoding and checking them are the same.

As I recall, C # has unsigned bytes (while Java is signed), so there are several places where there is room for things that subtly go wrong with byte signatures.

+6
source share

I have encountered this problem before.

When I wrote code for encryption and decryption, for example:

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sec, "AES"),new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] encode = cipher.doFinal(data); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sec, "AES"), new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] decode = cipher.doFinal(encode); 

I forgot the first IvParameterSpec(new byte[cipher.getBlockSize()]) when encrypting the data, then I got the exception โ€œblocking block is corruptedโ€, so maybe you should check the encryption code.

+3
source share

As far as I know, AES is based on Rijndael, but the specification is not exactly the same. I would suggest checking the size of the key and block that you use for encryption in C #, and the sizes used in Java. ( . Pure differences between Rijndael and AES ).

+1
source share

DoFinal () was canceling the above code, and I ended up using only encryption streams instead of the update / doFinal approach. That way, I could use FileInputStream and my cipher as parameters for CipherInputStream, and then pass the output to a web browser through an OutputStream. The violation of the update and doFinal in their own method calls made the task difficult, and both methods were removed from the decrypter class (leaving one while loop, which read in pieces of data and displayed them in the browser). The Bouncy Castle provider is also not needed in this case, and PKCS5Padding was enough, which was given by SunJCE.

+1
source share

All Articles