Pramit Bhaumik
Pramit Bhaumik

Reputation: 51

javax.crypto.BadPaddingException -Doing Decryption by AES256 with Salt and IV

I am using AES with salt and IV to encrypt and decrypt a unique ID but Its giving javax.crypto.BadPaddingException while decrypting .

Full error stack trace giving each time while decrypting the data

javax.crypto.BadPaddingException: Given final block not properly padded null


at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at com.data.commons.security.impl.DataAESCrypt.decode(DataAESCrypt.java:84)
    at com.data.CryptoTest.main(CryptoTest.java:13)

Encryption Method -

private static final int PASSWORD_ITERATIONS = 65536;
private static final int KEY_LENGTH          = 256;
private static byte[] salt = new byte[16];
private static byte[] iv= new byte[16];
private static final String ALGORITHM = "AES/CBC/PKCS5Padding" ;


@Override
public String encode(String plainText) throws Exception {
    // TODO Auto-generated method stub
       try {
            SecureRandom random = new SecureRandom();

            random.nextBytes(salt);

            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            KeySpec spec = new PBEKeySpec(plainText.toCharArray(), salt, PASSWORD_ITERATIONS, KEY_LENGTH);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance(ALGORITHM);
            AlgorithmParameters params = cipher.getParameters();
             iv = params.getParameterSpec(IvParameterSpec.class).getIV();
             cipher.init(Cipher.ENCRYPT_MODE, secret);
            byte[] encryptedText = cipher.doFinal(plainText.getBytes("UTF-8"));


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            outputStream.write(salt);
            outputStream.write(iv);
            outputStream.write(encryptedText);

            System.out.println("Salt " + DatatypeConverter.printBase64Binary(salt) + " IV " + DatatypeConverter.printBase64Binary(iv) );

            return DatatypeConverter.printBase64Binary(outputStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

}

Decryption Method

public String decode(String encodedText) throws Exception {
    // TODO Auto-generated method stub
    try {
        byte[] ciphertext = DatatypeConverter.parseBase64Binary(encodedText);
        if (ciphertext.length < 48) {
            return null;
        }
        byte[] salt = Arrays.copyOfRange(ciphertext, 0, 16);
        byte[] iv = Arrays.copyOfRange(ciphertext, 16, 32);
        byte[] ct = Arrays.copyOfRange(ciphertext, 32, ciphertext.length);

        System.out.println("Salt " + DatatypeConverter.printBase64Binary(salt) + " IV " + DatatypeConverter.printBase64Binary(iv) );
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(encodedText.toCharArray(), salt, PASSWORD_ITERATIONS, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
        byte[] plaintext = cipher.doFinal(ct);

        return new String(plaintext, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;

}

I am new to JCA.

Upvotes: 0

Views: 303

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

You are using plainText.toCharArray() and encodedText.toCharArray() as password in PBEKeySpec. Instead, use an actual passphrase. Currently you can only get back the plaintext message when you know the plaintext message, which isn't all that useful. Decrypting it with the encoded ciphertext as input will certainly not work.

Upvotes: 1

Related Questions