AES算法的CBC和ECB两种工作模式(Java版)

一、AES算法
对称加密算法是使用一个密钥进行加密和解密。AES算法是目前应用最广泛的对称加密算法。

AES算法的密钥长度有128位、192位和256位的,工作模式有ECB、CBC、PCBC、CTR等,填充模式有NoPadding、PKCS5Padding、PKCS7Padding等。

二、ECB工作模式
ECB模式需要一个固定长度的密钥,固定的明文会生成固定的密文。

//AES算法ECB模式
public class ECB {
	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
			IllegalBlockSizeException, BadPaddingException {
		String message = "是大眼同学呦!";// 原文信息
		System.out.println("原始信息:" + message);
		byte[] secretKey = "1234567890abcdef".getBytes();// 128位密钥(16字节)
		// 加密:
		byte[] data = message.getBytes();
		byte[] encryped = encrypt(secretKey, data);
		System.out.println("加密内容:" + Base64.getEncoder().encodeToString(encryped));
		// 解密:
		byte[] decrypted = decrypt(secretKey, encryped);
		System.out.println("解密内容:" + new String(decrypted));
 
	}
 
	// 加密:传入参数密钥和原始内容的字节信息
	public static byte[] encrypt(byte[] secretKey, byte[] input) throws NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		// 创建密码对象,需要传入算法名称/工作模式/填充方式
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		// 根据secretKey(密钥)的字节内容,"恢复"秘钥对象
		SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
		// 初始化秘钥:设置加密模式ENCRYPT_MODE
		cipher.init(Cipher.ENCRYPT_MODE, keySpec);
		// 根据原始内容(字节),进行加密
		return cipher.doFinal(input);
	}
 
	// 解密:传入参数密钥和机密后内容的字节信息
	public static byte[] decrypt(byte[] secretKey, byte[] input) throws NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		// 创建密码对象,需要传入算法名称/工作模式/填充方式
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		// 根据secretKey(密钥)的字节内容,"恢复"秘钥对象
		SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
		 初始化秘钥:设置加密模式DECRYPT_MODE
		cipher.init(Cipher.DECRYPT_MODE, keySpec);
		// 根据加密内容(字节),进行加密
		return cipher.doFinal(input);
	}
}

三、CBC工作模式

CBC工作模式需要一个随机数作为IV参数,这样对于同一份明文,每次生成的密文都不同。

//AES算法CBC工作模式
public class CBC {
	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
			InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		String message = "是大眼同学呦!";// 原文信息
		System.out.println("原始信息:" + message);
		byte[] secretKey = "1234567890abcdef1234567890abcdef".getBytes();// 256位密钥(32字节)
		// 加密:
		byte[] data = message.getBytes();
		byte[] encrypted = encrypt(secretKey, data);
		System.out.println("加密内容:" + Base64.getEncoder().encodeToString(encrypted));
		// 解密:
		byte[] decrypted = decrypt(secretKey, encrypted);
		System.out.println("解密内容:" + new String(decrypted));
	}
 
	// 加密:传入参数密钥和原始内容的字节信息
	public static byte[] encrypt(byte[] secretKey, byte[] input)
			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
			InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		// 创建密码对象,需要传入算法名称/工作模式/填充方式
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		// 根据secretKey(密钥)的字节内容,"恢复"秘钥对象
		SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
		// CBC模式需要生成一个16 bytes的initialization vector(IV参数 )
		SecureRandom sr = SecureRandom.getInstanceStrong();
		byte[] iv = sr.generateSeed(16);// 生成16个字节的随机数
		System.out.println("IV参数:" + Arrays.toString(iv));// 输出IV参数
		IvParameterSpec ivps = new IvParameterSpec(iv); // 随机数封装成IvParameterSpec参数对象
		// 初始化秘钥:操作模式、秘钥、IV参数
		cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);
		// 根据原始内容(字节),进行加密
		byte[] data = cipher.doFinal(input);
		return join(iv, data);
	}
 
	// 解密:传入参数密钥和机密后内容的字节信息
	public static byte[] decrypt(byte[] secretKey, byte[] input)
			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
			InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		// 把input分割成IV和密文
		byte[] iv = new byte[16];
		byte[] data = new byte[input.length - 16];
		System.arraycopy(input, 0, iv, 0, 16);// IV参数
		System.arraycopy(input, 16, data, 0, data.length);// 密文
		System.out.println("IV参数:" + Arrays.toString(iv));// 输出IV参数
		// 创建密码对象,需要传入算法名称/工作模式/填充方式
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		// 根据secretKey(密钥)的字节内容,"恢复"秘钥对象
		SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
		// 回复IV参数
		IvParameterSpec ivps = new IvParameterSpec(iv);
		// 初始化秘钥:操作模式、秘钥、IV参数
		cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);
		return cipher.doFinal(data);
	}
 
	// 数组合并
	public static byte[] join(byte[] arr1, byte[] arr2) {
		byte[] arr = new byte[arr1.length + arr2.length];
		System.arraycopy(arr1, 0, arr, 0, arr1.length);
		System.arraycopy(arr2, 0, arr, arr1.length, arr2.length);
		return arr;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值