javax.crypto.BadPaddingException: Given final block not properly padded error while decryption

encryption, java

Solution

The code you presented works just fine. The error must lie in the code you haven't shared with us (i.e. the code that actually uses the `Cipher` objects).

I wrote the code below to test your question code:

public static void main(String[] args) throws Exception {

  Random random = new Random();
  byte[] key = new byte[32];
  random.nextBytes(key);

  byte[] plaintext = new byte[100];
  random.nextBytes(plaintext);

  Cipher enc = aes_Gen_with_Key(key);

  byte[] ciphertext = enc.doFinal(plaintext);
  byte[] iv = enc.getIV();

  Cipher dec = aes_Dec_with_Key(key, iv);

  byte[] recoveredPlaintext = dec.doFinal(ciphertext);

  System.out.println(Arrays.equals(plaintext, recoveredPlaintext));    
}

Note, I made your two methods static. You should do the same, as they don't use any instance variables.

Problem

I am doing encryption and decryption of data as follows but getting error ``` protected Cipher aes_Gen_with_Key(byte[] key) { Cipher cipher=null; try { byte[] key_hash = (key).toString().getBytes("UTF-8"); key_hash = Arrays.copyOf(key_hash, 32); // use only first 256 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key_hash, "AES"); cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); } catch (Exception e) { System.out.println("Error Occured"); } return cipher; } protected Cipher aes_Dec_with_Key(byte[] key,byte[] iv) { Cipher cipher=null; try { byte[] key_hash = (key).toString().getBytes("UTF-8"); key_hash = Arrays.copyOf(key_hash, 32); // use only first 256 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key_hash, "AES"); cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(iv)); } catch (Exception e) { System.out.println(e); } return cipher; } ``` With above 2 functions I am getting ciphers with which I am doing encryption and decryption, but getting javax.crypto.BadPaddingException: Given final block not properly padded as error. Length of decryption byte array is 752 and IV at decryption is 16 byte long. Can any one suggest? Here are few more relevant code blocks. Apologies for invalid use java naming conventions ``` // Key Class import java.io.Serializable; @SuppressWarnings("serial") public class Key implements Serializable{ byte[] gsmodp_hash=null; byte[] iv_pass=null; byte[] Nonce_Enc=null; byte[] iv_non=null; public Key() { } public Key(byte[] gsmodp_hash,byte[] iv_pass,byte[] Nonce_Enc,byte[] iv_non) { this.gsmodp_hash=gsmodp_hash; this.iv_pass=iv_pass; this.Nonce_Enc=Nonce_Enc; this.iv_non=iv_non; } } // Client side code JSONObject auth_step_obj=new JSONObject(); try { BigInteger gsmodp=get_modu_frm_server(receivePacket); BigInteger R2=get_R2_frm_server(receivePacket); BigInteger N2=get_N2_frm_server(receivePacket); N2=crypto.dec_NonceG(N2); BigInteger a=crypto.get_RandLong(); BigInteger gamodp= crypto.dh_GenerationG(a, crypto.g, crypto.p); BigInteger key=crypto.dh_GenerationG(a, gsmodp, crypto.p); // Got hash of g^abmodp byte[] dhkey=crypto.sha256G(key.toString()); key=null; //Mixing passwords SecretKey secretkey=(SecretKey) userCredentials.get("password"); byte[] mixed_hash=crypto.passwordMixerG(R2, secretkey.getEncoded()); //Working Fine Till now // Getting Cipher for encrypting gsmodp using password and nonce Cipher cipher_password=crypto.aes_Gen_with_Key(mixed_hash); Cipher cipher_key=crypto.aes_Gen_with_Key(dhkey); // Generating quantities for JSON Object byte[] gsmodp_hash=cipher_password.doFinal(gamodp.toString().getBytes()); byte[] gsmodp_hash_iv=cipher_password.getIV(); byte[] nonce_enc=cipher_key.doFinal(N2.toString().getBytes()); byte[] nonce_enc_iv=cipher_key.getIV(); Key authetication_parameters=new Key(gsmodp_hash,gsmodp_hash_iv,nonce_enc,nonce_enc_iv); auth_step_obj.put("obj",authetication_parameters); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("Hi:sec_DH_Step"); } // This sends JSONObject to calling method which generates UDP packet and sends to server return auth_step_obj; } // Server side code // Once packet received on server following happens ds.receive(receivePacket); SecretKey userKey=cryptoObj.get_from_KeyStoreG(user_name); // Adding R2 and userKey byte by byte byte[] mixed_hash=cryptoObj.passwordMixerG(R2, userKey.getEncoded()); JSONObject authentication_nonce=new JSONObject(); authentication_nonce=cryptoObj.readRecievedPacket(receivePacket); Key obj=(Key)authentication_nonce.get("obj"); Cipher cipher=cryptoObj.aes_Dec_with_Key(mixed_hash,obj.iv_pass); // I am getting error on do final System.out.println(new String(cipher.doFinal(obj.gsmodp_hash))); ```

Original source