Skip to content

Instantly share code, notes, and snippets.

@kcak11
Last active February 20, 2024 16:35
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kcak11/86f73703eff5bbd2f7bd6b6b3efded34 to your computer and use it in GitHub Desktop.
Save kcak11/86f73703eff5bbd2f7bd6b6b3efded34 to your computer and use it in GitHub Desktop.
AES/CBC/PKCS5PADDING - Java/Javascript (Encryption & Decryption)

AES/CBC/PKCS5PADDING - Java/Javascript (Encryption & Decryption)

package com.ashish.crypto;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtil {
public static void main(String args[]) throws Exception {
byte[] cipherText = encrypt("Testing AES/CBC/PKCS5PADDING stuff from Java and with JavaScript - some random text".getBytes(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456".getBytes()); // 32 length Key
System.out.println(new String(cipherText));
byte[] origText = decrypt(new String(cipherText).getBytes(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456".getBytes());
System.out.println(new String(origText));
}
public static byte[] encrypt(byte[] plainTextData, byte[] secretKey) throws Exception {
try {
String iv = new String(secretKey).substring(0, 16);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
byte[] dataBytes = plainTextData;
int plaintextLength = dataBytes.length;
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(secretKey, "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return new String(Base64.getEncoder().encode(encrypted)).getBytes();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] decrypt(byte[] cipherTextData, byte[] secretKey) throws Exception {
try {
String iv = new String(secretKey).substring(0, 16);
byte[] encrypted = Base64.getDecoder().decode(cipherTextData);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec keyspec = new SecretKeySpec(secretKey, "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted);
String originalString = new String(original);
return originalString.getBytes();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
var secretkey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456'; //Length 32
var key = CryptoJS.enc.Utf8.parse(secretkey);
var iv = CryptoJS.enc.Utf8.parse(secretkey.substring(0, 16));
/*-- Encryption --*/
var cipherText = CryptoJS.AES.encrypt("Testing AES/CBC/PKCS5PADDING stuff from Java and with JavaScript - some random text", key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
console.log(cipherText);
/*-- Decryption --*/
var decrypted = CryptoJS.AES.decrypt("RQ/SEoGFF9IHmiMNbo/vlPTHuPWCGgDeEK5ZZBZjk/Kh5AIdgmVEeD42gciaK7gDKMP9odpjjZB/PGjebwpYSLzvEONS2jUiDtGPj7C0iNexmK5v5Gw9C8jsvqJdlmVK", key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
@ashish-primetech
Copy link

80df547a8f0a402eashish radadiya test @123

response getting wrong

@kcak11
Copy link
Author

kcak11 commented Feb 1, 2023

Please check the version of CryptoJS library.
Try out here: https://crypto.kcak11.com/

@ashish-primetech
Copy link

ashish-primetech commented Feb 3, 2023

I try to convert this code into node
your code is very similar way to work but Output like this

80df547a8f0a402eashish radadiya test @123

I'm stuck how to improve better way

@ashish-primetech
Copy link


import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Base64;

public class AESCBCPKCS5Encryption {

  private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  public static String encrypt(String message, String key) throws GeneralSecurityException, UnsupportedEncodingException {
    if(message == null || key == null){
      throw new IllegalArgumentException("text to be encrypted and key should not be null");
    }
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    byte[] messageArr = message.getBytes();
    byte[] keyparam=key.getBytes();
    SecretKeySpec keySpec = new SecretKeySpec(keyparam, "AES");
    byte[] ivParams = new byte[16];
    byte[] encoded = new byte[messageArr.length + 16];
    System.arraycopy(ivParams,0,encoded,0,16);
    System.arraycopy(messageArr, 0, encoded, 16, messageArr.length);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
    byte[] encryptedBytes = cipher.doFinal(encoded);
    encryptedBytes = Base64.getEncoder().encode(encryptedBytes);
    return new String(encryptedBytes);
  }
  public static String decrypt(String encryptedStr, String key) throws GeneralSecurityException, UnsupportedEncodingException {
    if(encryptedStr == null || key == null){
      throw new IllegalArgumentException("text to be decrypted and key should not be null");
    }
   Cipher cipher = Cipher.getInstance(ALGORITHM);
   byte[] keyparam=key.getBytes();
    SecretKeySpec keySpec = new SecretKeySpec(keyparam, "AES");
    byte[] encoded = encryptedStr.getBytes();
    encoded = Base64.getDecoder().decode(encoded);
    byte[] decodedEncrypted = new byte[encoded.length-16];
    System.arraycopy(encoded, 16, decodedEncrypted, 0,encoded.length-16);
    byte[] ivParams = new byte[16];
    System.arraycopy(encoded,0, ivParams,0, ivParams.length);
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
    byte[] decryptedBytes = cipher.doFinal(decodedEncrypted);
    return new String(decryptedBytes);
  }

  public static void main(String[] args) throws GeneralSecurityException, UnsupportedEncodingException {
    String str ="ashish radadiya test @123";
    String key ="80df547a8f0a402ead165f7f2798956d";
    String enc = encrypt(str, key);
    System.out.println(enc);
    String dec = decrypt("Av64GS6xSSFfzetmGyo7fAqP1ILpB9Be6JYrPHv3Z5Ty0dMOkEtfmbYr9ThEfkdT", key);
    System.out.println(dec);
  }
}

@kcak11
Copy link
Author

kcak11 commented Feb 3, 2023

I am not exactly sure what is the issue you are facing.
Can you share the input and the expected output.

In case you want to convert it to NodeJS, then you can find that code here:
https://github.com/kcak11/kcak11-api/blob/master/functions/routes/Crypto.js

Just for your awareness, the code does a RSA+AES Encryption and this is the output after encryption & decryption with your input at https://crypto.kcak11.com:

It does the following:

  1. Client creates a random encryption key i.e. (rek)
  2. Client encrypts (rek) with RSA Public Key (obtained via jwks.json endpoint) to get encrypted key i.e. (ekey)
  3. Client encrypts the actual data using AES algorithm with the random encryption key i.e. (rek) to get encrypted data i.e. (edata)
  4. Client then sends both (ekey) & (edata) to the server.
  5. The server has the RSA Private Key, so it decrypts (ekey) using the RSA Private Key to get the original encryption key i.e. (rek)
  6. Next the server uses AES algorithm to decrypt the (edata) with (rek) --> which gives the original data.

image

@khalidhabib
Copy link

work like charm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment