I need to send an encrypted string from Javascript to Android but I am getting the following error: javax.crypto.BadPaddingException: pad block corrupted
Unfortunately I cannot modify the Android implementation, I can only adapt the Javascript code. I have tried CryptoJS and now aes-js.
Android code to decrypt:
SecretKey secret_user_key = new SecretKeySpec(user_key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secret_user_key);
byte[] clearBytes = cipher.doFinal(encrypted);
Javascript to encrypt:
var aesCbc = new aesjs.ModeOfOperation.cbc(new Uint8Array(userKey));
var encrypted = aesCbc.encrypt(aesjs.padding.pkcs7.pad(clearByteArray));
The user key and the encrypted variables are the same on both platforms. Both user key and clearByteArray are 32 bytes.
Please note the Android implementation does not specify padding, iv nor mode of operation, but I can't modify that part.
I have tried a billion different combination of encryption parameters and have lost countless hours on this.
Edit: Also here is the equivalent encryption method on Android that I must reproduce on Javascript:
SecretKey secret_user_key = new SecretKeySpec(user_key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secret_user_key);
byte[] encrypted = cipher.doFinal(clearBytes);
return encrypted;
The mode Cipher.getInstance("AES");
that used in Android is ECB mode. ECB mode is insecure. You can see it from the penguin image at Wikipedia. You should use at least CBC mode or better authenticated encryption as AES-GCM mode.
Since you said that you cannot change the Android part then you have to downgrade the JS part to ECB mode.
var aesEcb = new aesjs.ModeOfOperation.ecb(key);