package com.tebon.ams.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.SecureRandom;

public class AESUtil {
/**
* 功能:生成AES秘钥并写入指定文件中
*
* @param filePath
* 文件夹绝对路径,必须是已存在文件
* @throws Exception
*/
public static void genAESKeyPair(String filePath) throws Exception {
// keySpec 生成对称密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");

try {
String publicKeyString = Base64.encodeBase64String(keySpec.getEncoded());
System.out.println(publicKeyString);

FileWriter pubfw = new FileWriter(filePath + "AESKey.key");
BufferedWriter pubbw = new BufferedWriter(pubfw);
pubbw.write(publicKeyString);

pubbw.flush();
pubbw.close();
pubfw.close();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 获取签名
*
* @param data
* 要加签的数据
* @param MD5key
* 加签时使用的key
* @return 签名字符
* @throws Exception
*/
public static String getSignature(String data, String MD5key) throws Exception {
data = data + "|" + MD5key; // data与key
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] b = md.digest(data.getBytes("UTF-8")); // md5签名
return Base64.encodeBase64String(b); // base64转码
};

/**
* AES加密
*
* @param plainTextData
* 要加密的数据
* @param key
* 加密时使用的key
* @return 返回加密后的数据
* @throws Exception
*/
public static String encryptAES(String plainTextData, String key) throws Exception {

// 密钥
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes());
kgen.init(128, secureRandom);

SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

// 加密数据
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encryptedData = cipher.doFinal(plainTextData.getBytes("UTF-8"));

return Base64.encodeBase64String(encryptedData); // base64转码
}

/**
* AES解密
*
* @param encryptedData
* 要解密的数据
* @param key
* 解密使用的key
* @return 解密后的数据
* @throws Exception
*/
public static String decryptAES(String encryptedData, String key) throws Exception {
// 密钥
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes());
kgen.init(128, secureRandom);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

// 解密数据
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decryptedData = cipher.doFinal(Base64.decodeBase64(encryptedData));

return new String(decryptedData, "UTF-8");
}

/**
* 验签
*
* @param encryptedSignature MD5加签的数�?
* @param plainTextData DATA明文
* @param key MD5 key
* @return
* @throws Exception
*/
public static boolean verify(String encryptedSignature, String plainTextData, String key) throws Exception {
String signature = getSignature(plainTextData, key);
if (encryptedSignature.equals(signature)) {
return true;
}
return false;
}

public static void main(String[] args) throws Exception {
// genAESKeyPair("c:/"); // 生成密钥
String sendStr =
"20171121|25|1|22195560|\r\n"
+"850|CON2015020449|刘崟波|N|13820666177|天津市|120105198001196035||1|37|M|首付款产品|0.16|360|0|FX|1|1|1|0|0|31480000|12592000|0|18888000|0|22195560|4624075|4444721|1|24|20150330|15|2015-04-15|2017-03-29|否||0|0|0|2015-03-26|沃尔沃|S|2010 款T5|沃尔�? C70(进口)|红色|YV1MC6755BJ112639|H|24|\r\n"
+"850|CON2015020449|2015-04-15|2015-04-15|924815|924815|\r\n"
+"850|CON2015020449|2015-05-15|2015-05-15|924815|924815|\r\n"
+"850|CON2015020449|2015-06-15|2015-06-16|924815|924815|\r\n"
+"850|CON2015020449|2015-07-15|2015-07-15|924815|924815|\r\n"
+"850|CON2015020449|2015-08-15|2015-08-15|924815|924815|\r\n"
+"850|CON2015020449|2015-09-15|2015-09-15|924815|924815|\r\n"
+"850|CON2015020449|2015-10-15|2015-10-16|924815|924815|\r\n"
+"850|CON2015020449|2015-11-15|2015-11-15|924815|924815|\r\n"
+"850|CON2015020449|2015-12-15|2015-12-15|924815|924815|\r\n"
+"850|CON2015020449|2016-01-15|2016-01-16|924815|924815|\r\n"
+"850|CON2015020449|2016-02-15|2016-02-15|924815|924815|\r\n"
+"850|CON2015020449|2016-03-15|2016-03-16|924815|924815|\r\n"
+"850|CON2015020449|2016-04-15|2016-04-15|924815|924815|\r\n"
+"850|CON2015020449|2016-05-15|2016-05-16|924815|924815|\r\n"
+"850|CON2015020449|2016-06-15|2016-06-15|924815|924815|\r\n"
+"850|CON2015020449|2016-07-15|2016-07-15|924815|924815|\r\n"
+"850|CON2015020449|2016-08-15|2016-08-16|924815|924815|\r\n"
+"850|CON2015020449|2016-09-15|2016-09-15|924815|924815|\r\n"
+"850|CON2015020449|2016-10-15|2016-10-16|924815|924815|\r\n"
+"850|CON2015020449|2016-11-15||924815|0|\r\n"
+"850|CON2015020449|2016-12-15||924815|0|\r\n"
+"850|CON2015020449|2017-01-15||924815|0|\r\n"
+"850|CON2015020449|2017-02-15||924815|0|\r\n"
+"850|CON2015020449|2017-03-30||924815|0|\r\n";


//加密过程
//MD5加签
String MD5Key = "vVwU4bhXdlSjWHMjxpCcbg==";
String md5Sign = AESUtil.getSignature(sendStr, MD5Key);

String AESKey = "qkMlGXKh0106YuZNW7guzA==";
String aesSendStr = md5Sign +"\r\n"+ sendStr;
System.out.println(md5Sign);

//对MD5加签后的结果进行AES加密
String encryptedData = AESUtil.encryptAES(aesSendStr, AESKey);

//验签过程
//AES解签
String decryptAESStr = AESUtil.decryptAES(encryptedData, AESKey);

//解签后获取Md5加签
String getMd5Sign = decryptAESStr.substring(0,aesSendStr.indexOf("\r\n"));
System.out.println(getMd5Sign);
//解签后获取明
String str = decryptAESStr.substring(aesSendStr.indexOf("\r\n")+2);
System.out.println(str);

//验签
boolean flag = AESUtil.verify(getMd5Sign, str, MD5Key);
System.out.println(flag);

}
}

AESUtil_1的更多相关文章

随机推荐

  1. [炼丹术]YOLOv5训练自定义数据集

    YOLOv5训练自定义数据 一.开始之前的准备工作 克隆 repo 并在Python>=3.6.0环境中安装requirements.txt,包括PyTorch>=1.7.模型和数据集会从 ...

  2. 加深理解Java异常概念并熟记5个最常见的运行时异常

    加深理解Java异常概念并熟记5个最常见的运行时异常 说明Error与Exception的联系和区别有哪些? 列举最常见的5个运用时异常. 1.Error和Exception的联系和区别: Error ...

  3. nginx worker_cpu_affinity使用方法

    Nginx默认没有开启利用多核CPU,我们可以通过增加worker_cpu_affinity配置参数来充分利用多核CPU.CPU是任务处理,计算最关键的资源,CPU核越多,性能就越好. 配置Nginx ...

  4. Sentry 企业级数据安全解决方案 - Relay 配置选项

    Relay 的配置记录在文件 .relay/config.yml 中.要更改此位置,请将 --config 选项传递给任何 Relay 命令: ❯ ./relay run --config /path ...

  5. IntelliJ IDEA 2020.1.1 x64 Debug 断点调试模式详解

    前言 对于初入职场的萌新们来说,很多都还不会 Debug 断点模式.记得我刚写代码的时候,也是通过 System.out.println() 一行一行的把变量打印出来看.其实强大的编辑器已经帮我们做好 ...

  6. RPC框架下实现文件上传到linux服务器

    一.前端使用element -ui 的upload组件 :data 表示额外传递的参数, :header 表示设置请求头参数,如,token等, action表示后台api接口的地址 二. conto ...

  7. Flask_上下文(六)

    Flask中有两种上下文,应用上下文(application context)和请求上下文(request context) 当客户端发来请求时,请求上下文就登场了.请求上下文里包含了请求的各种信息, ...

  8. MySQL主从复制作用和配置

    一.复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...

  9. spring boot + redis --- 心得

    1.前言 习惯使用springMVC 配置 redis ,现在使用spring boot ,得好好总结怎么在spring boot 配置和使用 ,区别真的挺大的. 2.环境 spring boot  ...

  10. Cookie.Session到Token和JWT

    一.session和cookie: 现在一般都是session和cookie一起用,一起提.但是他们俩其实不是一定要在一起. session的产生原因是,http协议是无状态的 这就导致了,不同的用户 ...