107 lines
3.4 KiB
Java
107 lines
3.4 KiB
Java
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());
|
|
}
|
|
}
|