|
|
@@ -0,0 +1,390 @@
|
|
|
+package com.dk.oauth.util;
|
|
|
+
|
|
|
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
+import sun.misc.BASE64Decoder;
|
|
|
+import sun.misc.BASE64Encoder;
|
|
|
+
|
|
|
+import javax.crypto.BadPaddingException;
|
|
|
+import javax.crypto.Cipher;
|
|
|
+import javax.crypto.IllegalBlockSizeException;
|
|
|
+import javax.crypto.NoSuchPaddingException;
|
|
|
+import javax.crypto.spec.IvParameterSpec;
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.io.PrintWriter;
|
|
|
+import java.net.URL;
|
|
|
+import java.net.URLConnection;
|
|
|
+import java.security.*;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+public class AesUtil {
|
|
|
+ public static boolean initialized = false;
|
|
|
+ // 算法名称
|
|
|
+ final String KEY_ALGORITHM = "AES";
|
|
|
+ // 加解密算法/模式/填充方式
|
|
|
+ final String algorithmStr = "AES/CBC/PKCS7Padding";
|
|
|
+ private Key key;
|
|
|
+ private Cipher cipher;
|
|
|
+ public void init(byte[] keyBytes) {
|
|
|
+
|
|
|
+ // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
|
|
|
+ int base = 16;
|
|
|
+ if (keyBytes.length % base != 0) {
|
|
|
+ int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
|
|
|
+ byte[] temp = new byte[groups * base];
|
|
|
+ Arrays.fill(temp, (byte) 0);
|
|
|
+ System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
|
|
|
+ keyBytes = temp;
|
|
|
+ }
|
|
|
+ // 初始化
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
+ // 转化成JAVA的密钥格式
|
|
|
+ key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
|
|
|
+ try {
|
|
|
+ // 初始化cipher
|
|
|
+ Cipher cipher = Cipher.getInstance(algorithmStr);
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (NoSuchPaddingException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 加密
|
|
|
+ public static String Encrypt(String sSrc, String sKey) throws Exception {
|
|
|
+ if (sKey == null) {
|
|
|
+ // System.out.print("Key为空null");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 判断Key是否为16位
|
|
|
+ if (sKey.length() != 16) {
|
|
|
+ // System.out.print("Key长度不是16位");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ byte[] raw = sKey.getBytes();
|
|
|
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
|
|
|
+ IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
|
|
|
+ byte[] encrypted = cipher.doFinal(sSrc.getBytes());
|
|
|
+
|
|
|
+ return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加密
|
|
|
+ public static String Encrypt(String sSrc, String sKey, String sIv)
|
|
|
+ throws Exception {
|
|
|
+ sSrc = new BASE64Encoder().encode(sSrc.getBytes());
|
|
|
+ if (sKey == null) {
|
|
|
+ // System.out.print("Key为空null");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ int base = 16;
|
|
|
+ byte[] raw = sKey.getBytes();
|
|
|
+ // 判断Key是否为16位
|
|
|
+ if (sKey.length() != 16) {
|
|
|
+ // System.out.print("Key长度不是16位");
|
|
|
+ int groups = raw.length / base + (raw.length % base != 0 ? 1 : 0);
|
|
|
+ byte[] temp = new byte[groups * base];
|
|
|
+ Arrays.fill(temp, (byte) 0);
|
|
|
+ System.arraycopy(raw, 0, temp, 0, raw.length);
|
|
|
+ raw = temp;
|
|
|
+ }
|
|
|
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
|
|
|
+ IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
|
|
|
+ byte[] encrypted = cipher.doFinal(sSrc.getBytes());
|
|
|
+
|
|
|
+ return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解密
|
|
|
+ public static String Decrypt(String sSrc, String sKey) throws Exception {
|
|
|
+ try {
|
|
|
+ // 判断Key是否正确
|
|
|
+ if (sKey == null) {
|
|
|
+ // System.out.print("Key为空null");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 判断Key是否为16位
|
|
|
+ if (sKey.length() != 16) {
|
|
|
+ // System.out.print("Key长度不是16位");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ byte[] raw = sKey.getBytes("UTF-8");
|
|
|
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
|
|
+ IvParameterSpec iv = new IvParameterSpec(
|
|
|
+ "0102030405060708".getBytes());
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
|
|
|
+ byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
|
|
|
+ try {
|
|
|
+ byte[] original = cipher.doFinal(encrypted1);
|
|
|
+ String originalString = new String(original);
|
|
|
+ return originalString;
|
|
|
+ } catch (Exception e) {
|
|
|
+ // System.out.println(e.toString());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ // System.out.println(ex.toString());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解密
|
|
|
+ public static String Decrypt(String sSrc, String sKey, String sIv)
|
|
|
+ throws Exception {
|
|
|
+ try {
|
|
|
+ // 判断Key是否正确
|
|
|
+ if (sKey == null) {
|
|
|
+ // System.out.print("Key为空null");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ int base=16;
|
|
|
+ byte[] raw = sKey.getBytes();
|
|
|
+ // 判断Key是否为16位
|
|
|
+ if (sKey.length() != 16) {
|
|
|
+ // System.out.print("Key长度不是16位");
|
|
|
+ int groups = raw.length / base + (raw.length % base != 0 ? 1 : 0);
|
|
|
+ byte[] temp = new byte[groups * base];
|
|
|
+ Arrays.fill(temp, (byte) 0);
|
|
|
+ System.arraycopy(raw, 0, temp, 0, raw.length);
|
|
|
+ raw = temp;
|
|
|
+ }
|
|
|
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
|
|
+ IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
|
|
|
+ byte[] encrypted = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
|
|
|
+ try {
|
|
|
+ byte[] original = cipher.doFinal(encrypted);
|
|
|
+ String originalString = new String(original);
|
|
|
+ return originalString;
|
|
|
+ } catch (Exception e) {
|
|
|
+ // System.out.println(e.toString());
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ // System.out.println(ex.toString());
|
|
|
+ ex.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String sendPost(String url, String param) {
|
|
|
+ PrintWriter out = null;
|
|
|
+ BufferedReader in = null;
|
|
|
+ String result = "";
|
|
|
+ try {
|
|
|
+ URL realUrl = new URL(url);
|
|
|
+ // 打开和URL之间的连接
|
|
|
+ URLConnection conn = realUrl.openConnection();
|
|
|
+ // 设置通用的请求属性
|
|
|
+ conn.setRequestProperty("accept", "*/*");
|
|
|
+ conn.setRequestProperty("connection", "Keep-Alive");
|
|
|
+ conn.setRequestProperty("user-agent",
|
|
|
+ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
|
|
|
+ // 发送POST请求必须设置如下两行
|
|
|
+ conn.setDoOutput(true);
|
|
|
+ conn.setDoInput(true);
|
|
|
+ // 获取URLConnection对象对应的输出流
|
|
|
+ out = new PrintWriter(conn.getOutputStream());
|
|
|
+ // 发送请求参数
|
|
|
+ out.print(param);
|
|
|
+ // flush输出流的缓冲
|
|
|
+ out.flush();
|
|
|
+ // 定义BufferedReader输入流来读取URL的响应
|
|
|
+ in = new BufferedReader(
|
|
|
+ new InputStreamReader(conn.getInputStream()));
|
|
|
+ String line;
|
|
|
+ while ((line = in.readLine()) != null) {
|
|
|
+ result += "\n" + line;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("发送POST请求出现异常!" + e);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 使用finally块来关闭输出流、输入流
|
|
|
+ finally {
|
|
|
+ try {
|
|
|
+ if (out != null) {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ if (in != null) {
|
|
|
+ in.close();
|
|
|
+ }
|
|
|
+ } catch (IOException ex) {
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * AES解密
|
|
|
+ *
|
|
|
+ * @param content
|
|
|
+ * 密文
|
|
|
+ * @return
|
|
|
+ * @throws InvalidAlgorithmParameterException
|
|
|
+ * @throws NoSuchProviderException
|
|
|
+ */
|
|
|
+ public static byte[] decrypt(byte[] content, byte[] keyBytes, byte[] ivByte)
|
|
|
+ throws InvalidAlgorithmParameterException {
|
|
|
+ initialize();
|
|
|
+ int base=16;
|
|
|
+ try {
|
|
|
+ if (keyBytes.length % base != 0) {
|
|
|
+ int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
|
|
|
+ byte[] temp = new byte[groups * base];
|
|
|
+ Arrays.fill(temp, (byte) 0);
|
|
|
+ System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
|
|
|
+ keyBytes = temp;
|
|
|
+ }
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
|
|
+ Key sKeySpec = new SecretKeySpec(keyBytes, "AES");
|
|
|
+
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
|
|
|
+ byte[] result = cipher.doFinal(content);
|
|
|
+ return result;
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (NoSuchPaddingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InvalidKeyException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (IllegalBlockSizeException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (BadPaddingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (NoSuchProviderException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void initialize() {
|
|
|
+ if (initialized)
|
|
|
+ return;
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
+ initialized = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成iv
|
|
|
+ public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
|
|
|
+ AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
|
|
|
+ params.init(new IvParameterSpec(iv));
|
|
|
+ return params;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * AES-128 CBC解密方式
|
|
|
+ *
|
|
|
+ * @param content 待解密的Base64字符串
|
|
|
+ * @param encodingFormat
|
|
|
+ * @param key 密钥
|
|
|
+ * @param initVector 初始化向量
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String aesCBCDecrypt(String content, String encodingFormat, String key, String initVector) {
|
|
|
+ try {
|
|
|
+ int base=16;
|
|
|
+ byte[] keyBytes=key.getBytes();
|
|
|
+ if (keyBytes.length % base != 0) {
|
|
|
+ int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
|
|
|
+ byte[] temp = new byte[groups * base];
|
|
|
+ Arrays.fill(temp, (byte) 0);
|
|
|
+ System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
|
|
|
+ keyBytes = temp;
|
|
|
+ }
|
|
|
+ SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
|
|
+ IvParameterSpec vector = new IvParameterSpec(initVector.getBytes());
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, vector);
|
|
|
+ //先用base64编码,因为对应的加密使用Base64解码
|
|
|
+ byte[] base64Bytes = new BASE64Decoder().decodeBuffer(content);
|
|
|
+ byte[] original = cipher.doFinal(base64Bytes);
|
|
|
+ String result = new String(original, encodingFormat);
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
+ /*
|
|
|
+ * 加密用的Key 可以用26个字母和数字组成,最好不要用保留字符,虽然不会错,至于怎么裁决,个人看情况而定
|
|
|
+ * 此处使用AES-128-CBC加密模式,key需要为16位。
|
|
|
+ */
|
|
|
+ // String cKey = "1234567890abcdef";
|
|
|
+ // JSONObject json1 = new JSONObject();
|
|
|
+ // json1.put("name", "1");
|
|
|
+ // JSONObject json = new JSONObject();
|
|
|
+ // json.put("name", json1.toString());
|
|
|
+ // // 需要加密的字串
|
|
|
+ // String cSrc = json.toString();
|
|
|
+ // System.out.println(cSrc);
|
|
|
+ // // 加密
|
|
|
+ // long lStart = System.currentTimeMillis();
|
|
|
+ // String enString = AesUtil.Encrypt(cSrc, cKey);
|
|
|
+ // System.out.println("加密后的字串是:" + enString);
|
|
|
+ //
|
|
|
+ // long lUseTime = System.currentTimeMillis() - lStart;
|
|
|
+ // System.out.println("加密耗时:" + lUseTime + "毫秒");
|
|
|
+ // // 解密
|
|
|
+ // lStart = System.currentTimeMillis();
|
|
|
+ //
|
|
|
+ // String DeString =
|
|
|
+ // "2dgKpMudbxK8oVuMqjIqZ20wehgGBy/jPTrU5Ztp4rebpehVSDe+rp2jalOXx2ZI3qtbZEZ9K1Vu\n"
|
|
|
+ // +
|
|
|
+ // "/lXPDL34pzv/VDZZh903fdW2AHR3HFkj49cyjVn8QbiMUxls7k8ZLdzX/YloxEHfpj7W1Q9TM9CS\n"
|
|
|
+ // +
|
|
|
+ // "BSqok6iM7f3oQ4E4KoaylKRJzdeW5j7pr6H1EY10Zj1oDr4U5dU1U9eD8IRB2FzUN4rlKzBuX30M\n"
|
|
|
+ // +
|
|
|
+ // "BmEIvcQr7I9FBjXmh9a5F/b8oUdOsBaAMuVZbHB5bb41n9snA76NKtzqoJjD7mAxSQXCcS2AE2p5\n"
|
|
|
+ // +
|
|
|
+ // "t2jgtmUpYHzzKLnbrCppSjEXQ263ni4YAo8cDOg2NpgnMKBwVZR+E1oDmS7RDMOtbDBBnnyqhlxM\n"
|
|
|
+ // +
|
|
|
+ // "HAPXsXxyGID7HExzPqfHbPDAEwBzs0CJUq9BTAWRdWL3yIePPHk3k1N21dcqmvvnfXfB56+dymMF\n"
|
|
|
+ // + "il+CJxvykh8iypPXO7oV+W5gZO3K1VKHKqE=";
|
|
|
+ // System.out.println(DeString.length());
|
|
|
+ // DeString = AesUtil.Decrypt(DeString, cKey);
|
|
|
+ // System.out.println("解密后的字串是:" + DeString);
|
|
|
+ // lUseTime = System.currentTimeMillis() - lStart;
|
|
|
+ // System.out.println("解密耗时:" + lUseTime + "毫秒");
|
|
|
+
|
|
|
+ // String ss = sendPost(
|
|
|
+ // "http://10.58.160.37:8081/gllaPlatFront/memberInfo.do?accountNo=12&passWord=C20AD4D76FE97759AA27A0C99BFF6710",
|
|
|
+ // "");
|
|
|
+ // System.out.println(ss.length());
|
|
|
+
|
|
|
+ // ss = AesUtil.Decrypt(ss, cKey);
|
|
|
+ // System.out.println("解密后的字串是:" + ss);
|
|
|
+ // System.out.println(URLDecoder.decode(ss, "utf-8"));
|
|
|
+ System.out.println(new Date().getTime());
|
|
|
+ String sSrc = "P20171208164708782" + "1537495349" + "IcBO0oUYWS*a";
|
|
|
+ String sKey = "IcBO0oUYWS*a";
|
|
|
+ String sIv = "4343435455545552";
|
|
|
+ String enString = AesUtil.Encrypt(sSrc, sKey, sIv);
|
|
|
+ System.out.println("加密后的字串是:" + enString);
|
|
|
+ String ss = "zIeJSkuGPpWha/JjbwZWc2DHzAamcztUPlKyJK/VSQMmJSVgnNpApy+N8vc/2fShyuzCaP2wNdcw8X82fUrsxy77lMjgZ9DO1rwebaU0ORs=";
|
|
|
+ //请求方解密数据 公共key
|
|
|
+ String public_key = "tuniaokeji000000";
|
|
|
+ //请求方解密数据 公共iv
|
|
|
+ String public_iv = "2015031320180313";
|
|
|
+ String ensString = AesUtil.Decrypt(ss, public_key, public_iv);
|
|
|
+ byte[] base64Bytes = new BASE64Decoder().decodeBuffer(ensString);
|
|
|
+ String result = new String(base64Bytes, "utf-8");
|
|
|
+ System.out.println("解密后的字串是:" + result);
|
|
|
+ }
|
|
|
+}
|