import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;
public class EmbedEncryptionUtil {
private static final int KEY_LENGTH = 256;
private static final int SALT_SIZE = 16;
private static final int IV_SIZE = 16;
private static final int ITERATION_COUNT = 65536;
private static final SecureRandom random = new SecureRandom();
public static String encryptAES256WithSecret(final String payload, final String secret) {
try {
byte[] salt = new byte[SALT_SIZE];
random.nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secret.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);
byte[] key = factory.generateSecret(spec).getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
byte[] iv = new byte[IV_SIZE];
random.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encValue = cipher.doFinal(payload.getBytes(StandardCharsets.UTF_8));
Base64.Encoder enc = Base64.getEncoder().withoutPadding();
byte[] finalCiphertext = new byte[encValue.length+SALT_SIZE+IV_SIZE];
System.arraycopy(iv, 0, finalCiphertext, 0, IV_SIZE);
System.arraycopy(salt, 0, finalCiphertext, IV_SIZE, SALT_SIZE);
System.arraycopy(encValue, 0, finalCiphertext, IV_SIZE + SALT_SIZE, encValue.length);
return enc.encodeToString(finalCiphertext);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String decryptAES256WithSecret(final String encryptedPayload, final String secret) {
try {
byte[] encryptedData = Base64.getDecoder().decode(encryptedPayload);
byte[] salt = new byte[SALT_SIZE];
byte[] iv = new byte[IV_SIZE];
System.arraycopy(encryptedData, 0, iv, 0, iv.length);
System.arraycopy(encryptedData, iv.length, salt, 0, salt.length);
byte[] cipherText = new byte[encryptedData.length - SALT_SIZE - IV_SIZE];
System.arraycopy(encryptedData, SALT_SIZE + IV_SIZE, cipherText, 0, cipherText.length);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secret.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}