javanode.jsencryptionsecure-codingcode-security

Getting some error while decrypting text in Java


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.


Solution

  • 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;
    }