Skip to content
Advertisement

Getting BadPaddingException due to byte[] too long to decipher

The following code is tested for short strings, in that case it decrypts the string nicely.

byte[] ciphertext = Base64.decode(myverylongstring,Base64.DEFAULT);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(Charset.forName("UTF-8")));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

byte[] decryptedtextByte = cipher.doFinal(ciphertext);
String decryptedtext = new String(decryptedtextByte); //Successfully decrypts the string
System.out.println("decryptedtext: " + decryptedtext);
[...]
} catch (BadPaddingException e) {
        e.printStackTrace();
}

But if the string is too large I get fired the exception I mention.

What could I do so it decrypts the string correctly maintaining the same large string to decrypt?

Edit, well technically what’s decrypted is a byte[], changing title and adding code to not cause possible confussion.

Advertisement

Answer

As you did not show the encryption and we do not know what kind of key you are using there are many possible reasons for failure. As well you did not show the imports so I could just argue what Base64-encoder is in use.

Below you find a simple program that does the en- and decryption a byte array that is much larger than the size you are using.

Edit: Security warning: The code below uses a stringified key and static IV, uses single part encryption / decryption for a huge byte array, uses the older CBC mode.

Please do not copy below code or use it in production – it is for educational purposes only.

The code does not have any proper exception handling !

It generates a (random filled) byte array with the plaintext and gets the key & iv from strings that are converted to byte[] using the Standard.Charset “UFT-8”.

That it’s doing the encryption, convert the ciphertext to a Base64 encoded string followed by the decoding to a new ciphertext byte[] and decryption with the same key and iv.

In the end there is simple comparison of the plaintext and decryptedtext byte arrays.

My advice it is to check for any forgotten charset-setting and correct (means identical) usage of key and iv.

code:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

public class Main {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        System.out.println("https://stackoverflow.com/questions/63143007/getting-badpaddingexception-due-to-byte-too-long-to-decipher");

        byte[] plaintext = new byte[100000];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(plaintext); // generate a random filled byte array

        byte[] key = "12345678901234567890123456789012".getBytes(StandardCharsets.UTF_8);
        byte[] iv = "1234567890123456".getBytes(StandardCharsets.UTF_8);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] ciphertextEnc = cipher.doFinal(plaintext);
        String ciphertextBase64 = Base64.getEncoder().encodeToString(ciphertextEnc);

        byte[] ciphertextDec = Base64.getDecoder().decode(ciphertextBase64);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] decryptedtextByte = cipher.doFinal(ciphertextDec);
        System.out.println("decryptedtextByte equals plaintext: " + Arrays.equals(plaintext, decryptedtextByte));
    }
}
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement