package com.rjconsultores.ventaboletos.web.utilerias.security; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; public class AESGSMHelper { private final String SECRET_KEY = "RJ@2019#c0n5ul10r35"; private final String SALT = "HrqoFr44GtkAhhYN+jP8Ag=="; private final String ENCRYPT_ALGO = "AES/GCM/NoPadding"; private final int TAG_LENGTH_BIT = 128; private final int IV_LENGTH_BYTE = 12; private final Charset UTF_8 = StandardCharsets.UTF_8; public String encrypt(String value) throws Exception { SecretKey secret = getAESKeyFromPassword(SECRET_KEY.toCharArray()); byte[] pText = value.getBytes(StandardCharsets.UTF_8); byte[] iv = getRandomNonce(12); byte[] cipherText = encrypt(pText, secret, iv); byte[] cipherTextWithIv = ByteBuffer.allocate(iv.length + cipherText.length) .put(iv) .put(cipherText) .array(); return hex(cipherTextWithIv); } private byte[] encrypt(byte[] pText, SecretKey secret, byte[] iv) throws Exception { Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); cipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); byte[] encryptedText = cipher.doFinal(pText); return encryptedText; } public String decrypt(String value) throws Exception { SecretKey secret = getAESKeyFromPassword(SECRET_KEY.toCharArray()); byte[] cText = unhex(value); ByteBuffer bb = ByteBuffer.wrap(cText); byte[] iv = new byte[IV_LENGTH_BYTE]; bb.get(iv); byte[] cipherText = new byte[bb.remaining()]; bb.get(cipherText); String plainText = decrypt(cipherText, secret, iv); return plainText; } private String decrypt(byte[] cText, SecretKey secret, byte[] iv) throws Exception { Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); cipher.init(Cipher.DECRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); byte[] plainText = cipher.doFinal(cText); return new String(plainText, UTF_8); } private byte[] getRandomNonce(int numBytes) { byte[] nonce = new byte[numBytes]; new SecureRandom().nextBytes(nonce); return nonce; } private SecretKey getAESKeyFromPassword(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec spec = new PBEKeySpec(password, SALT.getBytes(), 65536, 256); SecretKeySpec secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); return secret; } private String hex(byte[] bytes) { char[] result = Hex.encodeHex(bytes); return new String(result); } private byte[] unhex(String hex) throws DecoderException { return Hex.decodeHex(hex.toCharArray()); } }