· 9 years ago · Oct 03, 2016, 07:34 AM
1import java.io.File;
2import java.io.FileInputStream;
3import java.io.FileOutputStream;
4import java.io.IOException;
5import java.nio.charset.Charset;
6import java.security.GeneralSecurityException;
7import java.security.NoSuchAlgorithmException;
8import java.security.SecureRandom;
9import java.util.Base64;
10
11import javax.crypto.Cipher;
12import javax.crypto.KeyGenerator;
13import javax.crypto.SecretKey;
14import javax.crypto.spec.GCMParameterSpec;
15import javax.crypto.spec.SecretKeySpec;
16
17public enum AES {
18
19 INSTANCE;
20
21 private static final String CIPHER_ALGORITHM = "AES";
22 private static final String ALGORITHM_MODE_PADDING = "AES/GCM/NoPadding";
23
24 private static final int IV_LENGTH_BYTES = 16;
25 private static final int AES_KEY_SIZE = 128;
26 private static final int GCM_TAG_LENGTH = 128;
27
28 public String encrypt(String plainText, String authenticationTag) throws GeneralSecurityException, IOException {
29 createKeyFile(authenticationTag);
30 Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
31 final int blockSize = cipher.getBlockSize();
32 SecretKey secretKey = readKeyFile(authenticationTag);
33 byte[] plainTextByte = plainText.trim().getBytes(Charset.forName("UTF-8"));
34 byte[] ivBytes = generateIV();
35 cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(GCM_TAG_LENGTH, ivBytes));
36 cipher.updateAAD(authenticationTag.getBytes(Charset.forName("UTF-8")));
37 byte[] encryptedMessage = cipher.doFinal(plainTextByte);
38 byte iv_and_encryptedMessage[] = concatIvAndCipher(ivBytes, encryptedMessage, blockSize);
39 Base64.Encoder encoder = Base64.getEncoder().withoutPadding();
40 String iv_and_encryptedText = encoder.encodeToString(iv_and_encryptedMessage);
41 return iv_and_encryptedText;
42 }
43
44 public String decrypt(String iv_and_encryptedTextBase64, String authenticationTag)
45 throws GeneralSecurityException, IOException {
46 Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
47 final int blockSize = cipher.getBlockSize();
48 Base64.Decoder decoder = Base64.getDecoder();
49 byte[] iv_and_encryptedMessage = decoder.decode(iv_and_encryptedTextBase64.trim());
50 byte[] ivBytes = extractIvFrom(iv_and_encryptedMessage, blockSize);
51 byte[] encryptedTextBytes = extractEncryptedMessageFrom(iv_and_encryptedMessage, blockSize);
52 SecretKey secretKey = readKeyFile(authenticationTag);
53 cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(GCM_TAG_LENGTH, ivBytes));
54 cipher.updateAAD(authenticationTag.getBytes(Charset.forName("UTF-8")));
55 byte[] decryptedByte = cipher.doFinal(encryptedTextBytes);
56 String decryptedMessage = new String(decryptedByte, Charset.forName("UTF-8"));
57 return decryptedMessage;
58 }
59
60 private SecretKey readKeyFile(String tag) {
61
62 }
63
64 private void createKeyFile(String tag) {
65
66 }
67
68 public byte[] generateIV() throws NoSuchAlgorithmException {
69 SecureRandom random = new SecureRandom();
70 byte[] ivBytes = new byte[IV_LENGTH_BYTES];
71 random.nextBytes(ivBytes);
72 return ivBytes;
73 }
74
75 public byte[] concatIvAndCipher(byte[] iv, byte[] cipher, int blockSize) {
76 final byte[] ivAndEncryptedMessage = new byte[iv.length + cipher.length];
77 System.arraycopy(iv, 0, ivAndEncryptedMessage, 0, blockSize);
78 System.arraycopy(cipher, 0, ivAndEncryptedMessage, blockSize, cipher.length);
79 return ivAndEncryptedMessage;
80 }
81
82 public byte[] extractIvFrom(byte[] iv_and_encryptedMessage, int blockSize) {
83 byte[] ivBytes = new byte[blockSize];
84 System.arraycopy(iv_and_encryptedMessage, 0, ivBytes, 0, blockSize);
85 return ivBytes;
86 }
87
88 public byte[] extractEncryptedMessageFrom(byte[] iv_and_encryptedMessage, int blockSize) {
89 byte[] encryptedTextBytes = new byte[iv_and_encryptedMessage.length - blockSize];
90 System.arraycopy(iv_and_encryptedMessage, blockSize, encryptedTextBytes, 0, encryptedTextBytes.length);
91 return encryptedTextBytes;
92 }
93}