AES/CBC/PKCS5Padding issue

14,710

Solution 1

Cipher.update returns a byte[] as well. So you are missing part of the encrypted data when you go to decrypt. Update the last section to read as follows:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] someData = c.update(textData);
byte[] moreData = c.doFinal();

System.out.println("E: " + (someData.length + moreData.length));

c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, k, iv);
byte[] someDecrypted = c.update(someData);
byte[] moreDecrypted = c.doFinal(moreData);

System.out.println("R: " + (someDecrypted.length + moreDecrypted.length));

Solution 2

You can forgo the calls to update and just pass the byte[] data directly to doFinal performing the operation of encrypting or decrypting in one step.

Share:
14,710
Sergey Mashkov
Author by

Sergey Mashkov

Updated on June 04, 2022

Comments

  • Sergey Mashkov
    Sergey Mashkov almost 2 years

    I am trying to encrypt and decrypt some simple text. But for some reason I am getting a strange error: javax.crypto.BadPaddingException. Why would JCE generates bytes that are not properly padded?

    I have the following code:

    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import java.security.SecureRandom;
    
    public class SimplestTest {
        public static void main(String[] args) throws Exception {
            SecureRandom rnd = new SecureRandom();
    
            String text = "Hello, my dear! ... " + System.getProperty("user.home");
            byte[] textData = text.getBytes();
    
            IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16));
    
            KeyGenerator generator = KeyGenerator.getInstance("AES");
            generator.init(128);
            SecretKey k = generator.generateKey();
    
            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
            c.init(Cipher.ENCRYPT_MODE, k, iv);
            c.update(textData);
            byte[] data = c.doFinal();
    
            System.out.println("E: " + data.length);
    
            c = Cipher.getInstance("AES/CBC/PKCS5Padding");
            c.init(Cipher.DECRYPT_MODE, k, iv);
            c.update(data);
    
            System.out.println("R: " + c.doFinal().length);
        }
    
    }
    

    But for some reason it does not work. It fails with this exception:

    E: 16
    Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
            at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
            at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
            at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
            at javax.crypto.Cipher.doFinal(DashoA13*..)
            at SimplestTest.main(SimplestTest.java:31)
    

    What's going wrong? The data size is 16 bytes in length but is still "not properly padded" ?