· 7 years ago · Nov 14, 2018, 12:08 PM
1import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
2
3import javax.crypto.Cipher;
4import javax.crypto.spec.IvParameterSpec;
5import javax.crypto.spec.SecretKeySpec;
6
7public class AesCipher {
8
9 private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
10
11 private static int CIPHER_KEY_LEN = 16; //128 bits
12
13 public static String urlSafeBase64Encode(byte[] data) {
14 String encodeBase64 = Base64.encode(data);
15 String safeBase64Str = encodeBase64.replace('+', '-');
16 safeBase64Str = safeBase64Str.replace('/', '_');
17 safeBase64Str = safeBase64Str.replaceAll("=", "");
18 return safeBase64Str;
19 }
20
21 public static byte[] urlSafeBase64Decode(final String safeBase64Str) {
22 String base64Str = safeBase64Str.replace('-', '+');
23 base64Str = base64Str.replace('_', '/');
24 int mod4 = base64Str.length() % 4;
25 if (mod4 > 0) {
26 base64Str = base64Str + "====".substring(mod4);
27 }
28 return Base64.decode(base64Str);
29 }
30
31 /**
32 * AES-128-CBCåŠ å¯†
33 *
34 * @param key
35 * @param iv
36 * @param data
37 * @return
38 */
39 public static String encrypt(String key, String iv, String data) {
40
41 try {
42 IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
43 SecretKeySpec secretKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES");
44
45 Cipher cipher = Cipher.getInstance(AesCipher.CIPHER_NAME);
46 cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
47
48 byte[] encryptedData = cipher.doFinal((data.getBytes()));
49
50 String encryptedDataInBase64 = urlSafeBase64Encode(encryptedData);
51 String ivInBase64 = urlSafeBase64Encode(iv.getBytes("UTF-8"));
52
53 return encryptedDataInBase64 + ":" + ivInBase64;
54
55 } catch (Exception ex) {
56 throw new RuntimeException(ex);
57 }
58 }
59
60 private static String fixKey(String key) {
61
62 if (key.length() < AesCipher.CIPHER_KEY_LEN) {
63 int numPad = AesCipher.CIPHER_KEY_LEN - key.length();
64
65 for (int i = 0; i < numPad; i++) {
66 key += "0"; //0 pad to len 16 bytes
67 }
68
69 return key;
70
71 }
72
73 if (key.length() > AesCipher.CIPHER_KEY_LEN) {
74 return key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
75 }
76
77 return key;
78 }
79
80 /**
81 * AES-128-CBC解密
82 *
83 * @param key
84 * @param data
85 * @return
86 */
87
88 public static String decrypt(String key, String data) {
89
90 try {
91 String[] parts = data.split(":");
92
93 IvParameterSpec iv = new IvParameterSpec(urlSafeBase64Decode(parts[1]));
94 SecretKeySpec secretKey = new SecretKeySpec(fixKey(key).getBytes(), "AES");
95
96 Cipher cipher = Cipher.getInstance(AesCipher.CIPHER_NAME);
97 cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
98
99 byte[] decodedEncryptedData = urlSafeBase64Decode(parts[0]);
100
101 byte[] original = cipher.doFinal(decodedEncryptedData);
102
103 return new String(original);
104 } catch (Exception ex) {
105 throw new RuntimeException(ex);
106 }
107 }
108
109 public static void main(String[] args) {
110
111 String key = "9da76eb9f16e6ddf2de8eaf927d81c52"; // 128 bit key
112 String initVector = key.substring(0, 16); // 16 bytes IV, it is recommended to use a different random IV for every message!
113
114 String plain_text = "mima";
115 String encrypted = encrypt(key, initVector, plain_text);
116 System.out.println(encrypted);
117
118 String decrypt = decrypt(key, encrypted);
119 System.out.println(decrypt);
120 }
121}