原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重。

系列文章目录

RSA+AES数据传输的加密解密【篇】,项目实战(专题汇总)

  1. AES 加密解密简述 + 完美工具类 AESUtils
  2. RSA 加密解密,签名验签简述 + 完美工具类 RSAUtils
  3. RSA + AES 加密原理,一线大厂主流的加密手段
  4. RSA 与 AES 加密效率对比,用调研事实说明问题,用算法原理解决疑惑
  5. RSA + AES 混合加密策略,真实项目案例,一线大厂的主流HTTP加密交互方式(正在赶稿)

一、AES简介

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的),具体的加密流程如下图:

1. 流程图

在 AES 对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。

2. 特点

  1. 密钥只有一个,加密和解密使用同一个密钥;
  2. 长度与明文大致相同;
  3. 相比非对称加密速度很快;
  4. 安全性较非对称加密弱;
  5. 如果存在很多用户,那么相比非对称加密需要维护大量的密码,不利于管理;
  6. 要求提供一条安全的渠道使通讯双方在首次通讯时协商一个共同的密钥。直接的面对面协商可能是不现实而且难于实施的,所以双方可能需要借助于邮件和电话等其它相对不够安全的手段来进行协商;
  7. 对称加密算法一般不能提供信息完整性的鉴别。它无法验证发送者和接受者的身份。

所以,在实际生产中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。

二、AESUtils

工具类 RSAUtils,包含:

  1. 生成 AES 密钥;

  2. 获取 SecretKey 对象;

  3. AES 加密字符串;

  4. AES 解密字符串;

代码:AESUtils.java

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 功能:AES 工具类
 * 说明:
 * @author Mr.tjm
 * @date 2020-5-20 11:25
 */
@SuppressWarnings("all")
public class AESUtils {
	private static final Logger logger = LoggerFactory.getLogger(AESUtils.class);

	public final static String KEY_ALGORITHMS = "AES";
	public final static int KEY_SIZE = 128;

	/**
	 * 生成AES密钥,base64编码格式 (128)
	 * @return
	 * @throws Exception
	 */
	public static String getKeyAES_128() throws Exception{
		KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHMS);
		keyGen.init(KEY_SIZE);
		SecretKey key = keyGen.generateKey();
		String base64str = Base64.encodeBase64String(key.getEncoded());
		return base64str;
	}

	/**
	 * 生成AES密钥,base64编码格式 (256)
	 * @return 
	 * @throws Exception
	 */
	public static String getKeyAES_256() throws Exception{
		// 256需要换jar包暂时用128
		String base64str = getKeyAES_128();
		return base64str;
	}

	/**
	 * 根据base64Key获取SecretKey对象
	 * @param base64Key
	 * @return
	 */
	public static SecretKey loadKeyAES(String base64Key) {
		byte[] bytes = Base64.decodeBase64(base64Key);
		SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, KEY_ALGORITHMS);
		return secretKeySpec;
	}
	
	/**
	 * AES 加密字符串,SecretKey对象
	 * @param key
	 * @param encryptData
	 * @param encode
	 * @return
	 */
	public static String encrypt(SecretKey key, String encryptData, String encode) {
		try {
			final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptBytes = encryptData.getBytes(encode);
			byte[] result = cipher.doFinal(encryptBytes);
			return Base64.encodeBase64String(result);
		} catch (Exception e) {
			logger.error("加密异常:" + e.getMessage());
			return null;
		}
	}
	
	/**
	 * AES 加密字符串,base64Key对象
	 * @param base64Key
	 * @param encryptData
	 * @param encode
	 * @return
	 */
	public static String encrypt(String base64Key, String encryptData, String encode) {
		SecretKey key = loadKeyAES(base64Key);
		try {
			final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] encryptBytes = encryptData.getBytes(encode);
			byte[] result = cipher.doFinal(encryptBytes);
			return Base64.encodeBase64String(result);
		} catch (Exception e) {
			logger.error("加密异常:" + e.getMessage());
			return null;
		}
	}
	
	/**
	 * AES 解密字符串,SecretKey对象
	 * @param key
	 * @param decryptData
	 * @param encode
	 * @return
	 */
	public static String decrypt(SecretKey key, String decryptData, String encode) {
		try {
			final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] decryptBytes = Base64.decodeBase64(decryptData);
			byte[] result = cipher.doFinal(decryptBytes);
			return new String(result, encode);
		} catch (Exception e) {
			logger.error("加密异常:" + e.getMessage());
			return null;
		}
	}

	/**
	 * AES 解密字符串,base64Key对象
	 * @param base64Key
	 * @param decryptData
	 * @param encode
	 * @return
	 */
	public static String decrypt(String base64Key, String decryptData, String encode) {
		SecretKey key = loadKeyAES(base64Key);
		try {
			final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] decryptBytes = Base64.decodeBase64(decryptData);
			byte[] result = cipher.doFinal(decryptBytes);
			return new String(result, encode);
		} catch (Exception e) {
			logger.error("加密异常:" + e.getMessage());
			return null;
		}
	}
}

我是IT无知君,您的点赞、评论和关注,是我创作的动力源泉。
学无止境,气有浩然,让我们一起加油,天涯未远,江湖有缘再见!!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐