AES+RSA加密
一、说明
加密算法分 对称加密、非对称加密、散列。其中对称加密算法的的密钥相同;非对称加密算法的加密密钥与解密的密钥不同;散列算法不需要密钥
常见的对称加密算法主要有 DES
、3DES
、AES
...,常见的 非对称算法 主要有 RSA
、DSA
...,散列算法 主要有 SHA-1
、MD5
...
数据传输通常使用对称加密和非对称加密居多,其各自优缺点如下:
-
对称加密
- 优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。
- 缺点:一方的秘钥被泄露,加密信息也就不安全了。每对用户每次使用对称加密算法时,都需要使用他人不知道的唯一秘 钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理麻烦
-
非对称加密
-
优点:私钥只能由一方保管,不能外泄,公钥可以交给任何请求方。加密更为安全。
-
缺点:速度慢
二、AES
AES算法实现:https://blog.youkuaiyun.com/qq_28205153/article/details/55798628
三 、RSA
RSA算法实现:http://blog.youkuaiyun.com/lemon_tree12138/article/details/50696926
四、AES+RSA
AES和RSA有各自的优缺点,所以一般传输数据要把两种加密方法结合使用。数据用AES加密,然后用RSA对AES的秘钥进行加密。有时候为了更加安全会使用两对RSA秘钥,发送方分别用接收方的公钥和自己的私钥加密AES秘钥,接收方拿到密文先用发送方的公钥解密后再用自己的私钥解密得到AES秘钥,然后用AES秘钥去解密数据得到明文。
网上的RSA和AES的实现代码有很多,个人推荐使用Hutool工具包中封装好的接口
import java.util.Properties;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSONObject;
/**
* Description: 股权Servlet工具类
*
* @author xpf
*
* @date 2021-1-25
*
*/
public class cryptUtils {
/**
* Description:加密数据
*
* @param data (JSONString)
* @return 加密后的字符串
*/
public String encryptData(String data) throws Exception{
String result = "";
JSONObject jo = new JSONObject();
//密文参数存放在资源文件中,便于修改
Properties sourceProperties =
PropertiesFile.getProperties("/properties/Info.properties");
//profile:dev/pro
String mode = sourceProperties.getProperty("profile");
//srp为接收方,ifs为加密方
String srpPublicKey = sourceProperties.getProperty(mode+".srpPublicKey");
String ifsPrivateKey = sourceProperties.getProperty(mode+".ifsPrivateKey");
// 随机生成AES密钥
String aesKey = IdUtil.simpleUUID();
System.out.println("aesKey明文:" + aesKey);
//------1、先使用对方给的公钥加密aesKey-----------------
//srp的公钥
RSA rsa1 = new RSA(null,srpPublicKey);
byte[] encrypt = rsa1.encrypt(aesKey, KeyType.PublicKey);
System.out.println("使用srp公钥加密后:" + encrypt);
//------2、再使用ifs的私钥加密aesKey-----------------
//ifs的私钥
RSA rsa2 = new RSA(ifsPrivateKey, null);
String encryptAesKey = rsa2.encryptBase64(encrypt, KeyType.PrivateKey);
System.out.println("ifs的私钥加密后 aesKey:" + encryptAesKey);
//--------------使用随机生成的aesKey秘钥对需要传递的json数据进行加密
//使用AES明文,构建AES对象
byte[] key = StrUtil.bytes(aesKey, CharsetUtil.CHARSET_UTF_8);
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
String encryptedData= aes.encryptBase64(data);
//数据填充
//加密后的AES秘钥密文
jo.put("aesKey", encryptAesKey);
//AES加密后的数据密文
jo.put("data",encryptedData);
result = jo.toJSONString();
return result;
}
/**
* Description:解密数据
*
* @param array
* @return 解密后的字符串
*/
public String decryptData(String data) throws Exception{
String result = "";
Properties sourceProperties =
PropertiesFile.getProperties("/properties/GQInfo.properties");
String mode = sourceProperties.getProperty("mode");
//私钥
String srpPublicKey = sourceProperties.getProperty(mode+".srpPublicKey");
String ifsPrivateKey = sourceProperties.getProperty(mode+".ifsPrivateKey");
//appKey、aesKey(密文)、data(加密后的json数据)
String paramAesKey = "";
String paramData = "";
JSONObject paramJo = JSONObject.parseObject(data);
//校验是否包含AES秘钥字段
if(paramJo.containsKey("aesKey")){
paramAesKey = paramJo.getString("aesKey");
}else{
throw new Exception("ERROR_AESKEY");
}
if(paramJo.containsKey("data")){
paramData = paramJo.getString("data");
}
//------使用对方给的公钥解密aesKey-----------------
//srp公钥
String aesKey = "";
try{
//RSA解密(SRP公钥)
RSA rsa1 = new RSA(null, srpPublicKey);
byte[] decrypt = rsa1.decrypt(paramAesKey, KeyType.PublicKey);
//ifs使用私钥对密文解密
RSA rsa2 = new RSA(ifsPrivateKey, null);
decrypt = rsa2.decrypt(decrypt, KeyType.PrivateKey);
aesKey = StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
}catch(Exception e){
e.printStackTrace();
throw new Exception("ERROR_KEY");
}
System.out.println("使用股权平台公钥和园易融私钥解密后 的AesKey:" + aesKey);
//--------使用AESKey解密数据----------------------
//使用AES
byte[] key = StrUtil.bytes(aesKey, CharsetUtil.CHARSET_UTF_8);
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
String decryptedData = aes.decryptStr(paramData, CharsetUtil.CHARSET_UTF_8);
//data数据解析
JSONObject dataJo = JSONObject.parseObject(decryptedData);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//时间戳校验,超过5分钟为过期
if(dataJo.containsKey("timeStamp")){
long timeStamp = Long.parseLong(dataJo.getString("timeStamp"));
Date nowDate = new Date();
long diffDate = nowDate.getTime()-timeStamp;
//时间差(毫秒)
if(diffDate>300000L){
throw new Exception("TIME_OVER");
}
}else{
throw new Exception("ERROR_TIME");
}
result = decryptedData;
return result;
}
注意:上述代码为项目代码,加密是以IFS为发送方,解密是以IFS为接收方。
hutool工具包使用注意版本与JDK的兼容