0

I have below NodeJS code for decryption and it is working perfectly fine but when I am trying to convert the same code in Java at that time I am getting below error.

Given final block not properly padded. Such issues can arise if a bad key is used during decryption

Node JS code snippet:

  let textParts = text.split(':');
  let iv = Buffer.from(textParts.shift(), 'hex');
  let encryptedText = Buffer.from(textParts.join(':'), 'hex');
  let decrypted = decipher.update(encryptedText);
  let decipher = crypto.createDecipheriv(
    'aes-256-cbc',
    Buffer.from(ENCRYPTION_KEY),
    iv,
  );
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();

Java code snippet:

try {
    IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    byte[] original = cipher.doFinal(Base64.decodeBase64(encyptedData));
    return new String(original);
} catch (Exception ex) {
    ex.printStackTrace();
}

Encryption Key is same for both Node JS and Java code. Thanks in advance.

Jyubin Patel
  • 1,373
  • 7
  • 17
  • 1
    In the NodeJS code the ciphertext and IV are hex decoded, in the Java code the IV is UTF8 encoded and the ciphertext is Base64 decoded. Match the encodings in the Java code to those in the NodeJS code. You should also specify an encoding when decoding the plaintext (`new String(original,...)`). – Topaco Dec 16 '21 at 07:16
  • 1
    Btw, in the NodeJS code the `createDecipheriv()` call and the `update()` call are swapped. The code is not executable like this. – Topaco Dec 16 '21 at 07:37

2 Answers2

1

If your initial vector is 32 bytes then you need to decrypt as below.

public String decrypt(String encryptedData) {
    try {
        String data[] = encryptedData.split(":");
        IvParameterSpec iv = new IvParameterSpec(getBytes(data[0]));
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec skeySpec = new SecretKeySpec(YOUR_KEY.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] decryptedData = cipher.doFinal(getBytes(data[1]));
        return new String(decryptedData);
    } catch (Exception e) {
        throw new RuntimeException("Error occured while decrypting data", e);
    }
}

public byte[] getBytes(String s) {                   
    String tmp;
    byte[] b = new byte[s.length() / 2];
    int i;
    for (i = 0; i < s.length() / 2; i++) {
        tmp = s.substring(i * 2, i * 2 + 2);
        b[i] = (byte)(Integer.parseInt(tmp, 16) & 0xff);
    }
    return b;
}
Anup Ganatra
  • 366
  • 1
  • 6
  • 23
  • The NodeJS code uses Utf-8 for key and plaintext, the Java code applies the platform default encoding. If this differs from Utf-8, the code does not work reliably. Therefore, better specify the encoding! – Topaco Dec 17 '21 at 13:28
-2

it seems the problem is with size of the variabel in java when you decode. Check this links maybe those give you some hints :

1- ejava-base64-encode-and-decode

2- given-final-block-not-properly-padded

hamed
  • 1
  • 1
  • Please provide more than a link in your answers as they might be deleted if you don't provide any explanation https://stackoverflow.com/help/deleted-answers – git_gud Dec 16 '21 at 07:58