| 
					
				 | 
			
			
				@@ -0,0 +1,208 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package com.huaxu.util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import sun.misc.BASE64Decoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import sun.misc.BASE64Encoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.crypto.Cipher; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.crypto.KeyGenerator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import javax.crypto.SecretKey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.security.SecureRandom; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * AES是一个迭代的、对称密钥分组的密码,它可以使用128、192和256位密钥长度,并且用128位分组长度加密和解密数据。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * AES的加密过程:对数据的加密过程是通过把输入的明文和密钥由轮函数经N轮迭代来实现的,结尾轮与前N-1轮不同。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 前N-1轮依次进行S盒变换、行移位变换、列混淆变换和轮密钥加变换;第N轮与前N-1轮相比去掉了列混淆变换 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  @author lihui 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  @since 2021-03-23 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class AESUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 密钥长度: 128, 192 or 256 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final int KEY_SIZE = 128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 加密/解密算法名称 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final String ALGORITHM = "AES"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 随机数生成器(RNG)算法名称 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final String RNG_ALGORITHM = "SHA1PRNG"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 允许最大的时间差 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final int MAX_TIME = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 生成密钥对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static SecretKey generateKey(byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建安全随机数生成器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SecureRandom random = SecureRandom.getInstance(RNG_ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置 密钥key的字节数组 作为安全随机数生成器的种子 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        random.setSeed(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建 AES算法生成器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        KeyGenerator gen = KeyGenerator.getInstance(ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 初始化算法生成器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        gen.init(KEY_SIZE, random); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return gen.generateKey(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 数据加密: 明文 -> 密文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static byte[] encryptBye(byte[] plainBytes, byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成密钥对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SecretKey secKey = generateKey(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 获取 AES 密码器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cipher cipher = Cipher.getInstance(ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 初始化密码器(加密模型) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cipher.init(Cipher.ENCRYPT_MODE, secKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 加密数据, 返回密文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] cipherBytes = cipher.doFinal(plainBytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return cipherBytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 数据加密: 明文 -> 密文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static String encryptString(byte[] plainBytes, byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new BASE64Encoder().encode(encryptBye(plainBytes, key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 数据解密: 密文 -> 明文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static byte[] decryptByte(byte[] cipherBytes, byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成密钥对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SecretKey secKey = generateKey(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 获取 AES 密码器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cipher cipher = Cipher.getInstance(ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 初始化密码器(解密模型) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cipher.init(Cipher.DECRYPT_MODE, secKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 解密数据, 返回明文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] plainBytes = cipher.doFinal(cipherBytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return plainBytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 数据解密: 密文 -> 明文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static String decryptString(String cipherString, String key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new String(decryptByte(new BASE64Decoder().decodeBuffer(cipherString), key.getBytes()), "utf-8"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 数据验证: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 解密后的值再根据当前的时间进行加密 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 是否等同于 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 传过来的加密 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param  date 加密的时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param  text 明文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param  encryptValue 加密后内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param  appSecret 秘钥 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static boolean verifyEncrypt(String encryptValue, String text, Long date, String appSecret) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 获取当前时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            long differ   = Long.parseLong(DatesUtil.formatDate(new Date(), "yyyyMMddHHmm")) - date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (differ > MAX_TIME || differ < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 重新组装key,验证加密是否相同 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String encryptValue2 = encryptString((text + "_" + date).getBytes(), appSecret.getBytes()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return encryptValue2.equals(encryptValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 加密文件: 明文输入 -> 密文输出 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static void encryptFile(File plainIn, File cipherOut, byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        aesFile(plainIn, cipherOut, key, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 解密文件: 密文输入 -> 明文输出 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static void decryptFile(File cipherIn, File plainOut, byte[] key) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        aesFile(plainOut, cipherIn, key, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * AES 加密/解密文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void aesFile(File plainFile, File cipherFile, byte[] key, boolean isEncrypt) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 获取 AES 密码器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cipher cipher = Cipher.getInstance(ALGORITHM); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 生成密钥对象 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SecretKey secKey = generateKey(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 初始化密码器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 加密/解密数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        InputStream in = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        OutputStream out = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (isEncrypt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 加密: 明文文件为输入, 密文文件为输出 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                in = new FileInputStream(plainFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                out = new FileOutputStream(cipherFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 解密: 密文文件为输入, 明文文件为输出 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                in = new FileInputStream(cipherFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                out = new FileOutputStream(plainFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            byte[] buf = new byte[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int len = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 循环读取数据 加密/解密 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while ((len = in.read(buf)) != -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                out.write(cipher.update(buf, 0, len)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            out.write(cipher.doFinal());    // 最后需要收尾 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            out.flush(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            close(in); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            close(out); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void close(Closeable c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (c != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                c.close(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // nothing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static void main(String[] args) throws  Exception{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String appId      = "868083_1001_123456_202103241637";        // 原文内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String appSecret  = "123456";                    // AES加密/解密用的原始密码 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 加密数据, 返回密文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String cipherString = AESUtils.encryptString(appId.getBytes(), appSecret.getBytes()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 解密数据, 返回明文 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String plainString  = AESUtils.decryptString(cipherString, appSecret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println(cipherString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.out.println(plainString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //System.out.println(AESUtils.verifyEncrypt(cipherString, plainString, appSecret)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |