· 6 years ago · Jun 11, 2019, 12:18 PM
1package br.com.zup.ole.commons.utils.cipher;
2
3import java.security.NoSuchAlgorithmException;
4import java.security.Provider;
5import java.security.SecureRandom;
6import java.util.Base64;
7import java.util.Optional;
8
9import javax.crypto.Cipher;
10import javax.crypto.KeyGenerator;
11import javax.crypto.SecretKey;
12import javax.crypto.spec.IvParameterSpec;
13import javax.crypto.spec.SecretKeySpec;
14
15import org.slf4j.Logger;
16import org.slf4j.LoggerFactory;
17
18public class AESUtils {
19
20 private static final String TRANSFORMATION = "CBC/PKCS5Padding";
21 private static final String ALGORITHM = "AES";
22
23 private static final Logger LOGGER = LoggerFactory.getLogger(AESUtils.class);
24
25 private AESUtils() {
26 super();
27 }
28
29 public static String generateIvPass() {
30 try {
31 final SecureRandom rng = new SecureRandom();
32 final SecretKey aesKey = createKey(ALGORITHM, 128, Optional.empty(), Optional.of(rng));
33 final Cipher aesCBC = Cipher.getInstance(String.format("%s/%s", ALGORITHM, TRANSFORMATION));
34 final IvParameterSpec ivForCBC = createIV(aesCBC.getBlockSize(), Optional.of(rng));
35 String ivString = Base64.getEncoder().encodeToString(ivForCBC.getIV());
36 String keyString = Base64.getEncoder().encodeToString(aesKey.getEncoded());
37 return ivString + ":" + keyString;
38 } catch (Exception e) {
39 return null;
40 }
41 }
42
43 public static String encrypt(String iv, String key, String message) {
44 try {
45 IvParameterSpec ivSpec = new IvParameterSpec(Base64.getDecoder().decode(iv));
46 SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM);
47 Cipher cipher = Cipher.getInstance(String.format("%s/%s", ALGORITHM, TRANSFORMATION));
48 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
49 byte[] encrypted = cipher.doFinal(message.getBytes());
50 return Base64.getEncoder().encodeToString(encrypted);
51 } catch (Exception e) {
52 LOGGER.warn(String.format("Failed encrypt value: %s.", message), e);
53 }
54 return null;
55 }
56
57 public static String decrypt(String iv, String key, String message) {
58 try {
59 IvParameterSpec ivSpec = new IvParameterSpec(Base64.getDecoder().decode(iv));
60 SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM);
61 Cipher cipher = Cipher.getInstance(String.format("%s/%s", ALGORITHM, TRANSFORMATION));
62 cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
63 byte[] original = cipher.doFinal(Base64.getDecoder().decode(message));
64 return new String(original);
65 } catch (Exception e) {
66 LOGGER.warn(String.format("Failed decrypt value: %s.", message), e);
67 }
68 return null;
69 }
70
71 private static SecretKey createKey(final String algorithm, final int keysize, final Optional<Provider> provider,
72 final Optional<SecureRandom> rng) throws NoSuchAlgorithmException {
73 final KeyGenerator keyGenerator;
74 if (provider.isPresent()) {
75 keyGenerator = KeyGenerator.getInstance(algorithm, provider.get());
76 } else {
77 keyGenerator = KeyGenerator.getInstance(algorithm);
78 }
79
80 if (rng.isPresent()) {
81 keyGenerator.init(keysize, rng.get());
82 } else {
83 keyGenerator.init(keysize);
84 }
85
86 return keyGenerator.generateKey();
87 }
88
89 private static IvParameterSpec createIV(final int ivSizeBytes, final Optional<SecureRandom> rng) {
90 final byte[] iv = new byte[ivSizeBytes];
91 final SecureRandom theRNG = rng.orElse(new SecureRandom());
92 theRNG.nextBytes(iv);
93 return new IvParameterSpec(iv);
94 }
95
96 public static void main(String[] args) {
97
98 String iv = "D/0mfJ8ensipmQByEjv0SQ==";
99 String pass = "xjKWwlo9NXrd1etosCaeYg==";
100
101 System.out.println(AESUtils.decrypt(iv, pass, "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"));
102
103 }
104
105}