AES+RSA加密

AES+RSA加密

一、说明

加密算法分 对称加密、非对称加密、散列。其中对称加密算法的的密钥相同;非对称加密算法的加密密钥与解密的密钥不同;散列算法不需要密钥

常见的对称加密算法主要有 DES3DESAES ...,常见的 非对称算法 主要有 RSADSA ...,散列算法 主要有 SHA-1MD5 ...

数据传输通常使用对称加密和非对称加密居多,其各自优缺点如下:

  • 对称加密

  • 优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。
  • 缺点:一方的秘钥被泄露,加密信息也就不安全了。每对用户每次使用对称加密算法时,都需要使用他人不知道的唯一秘 钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理麻烦
  • 非对称加密

  • 优点私钥只能由一方保管,不能外泄,公钥可以交给任何请求方。加密更为安全。

  • 缺点:速度慢

二、AES 

AES算法实现:https://blog.csdn.net/qq_28205153/article/details/55798628 

三 、RSA

RSA算法实现:http://blog.csdn.net/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的兼容

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值