AES算法

AES是常见的对称加密算法,有ECB和CBC等工作模式。ECB模式中相同的明文会生成相同的密文,安全性较低;而CBC模式引入随机IV,每次加密同一明文都会得到不同密文,提高了安全性。文章提供了Java实现AESECB和CBC模式加密解密的示例代码。
摘要由CSDN通过智能技术生成

目录

一、AES算法

二、AES的工作模式

三、AES算法的CBC模式和EBC模式的区别


一、AES算法

        AES(Advandced Encryption Standard)是对称加密算法常用的的一种加密算法。对称加密算法就是传统的用一个秘钥进行加密和解密,我们常用的WinZIP和WinRAR对压缩包的加密和解密,就是使用对称加密算法。

        具体来说,加密是将收到密码和明文加密成密文,解密则是根据密码和密文解密出明文输出。

        它是一种分组加密标准,每个加密块大小128位,允许的密钥长度为128(16个字节)、192(24个字节)和256位(32个字节)。

二、AES的工作模式

        1、ECB模式

                ECB(Electronic codebook:电子密码本模式),是最简单的AES加密模式,它需要一个固定长度的密钥,固定的明文会产生固定的密文。

        2、CBC模式

              CBC (Cipher-block chaining:密码分组链接),引入了一个随机的IV参数,有效的解决了ECB模式下固定的明文产生固定的密文导致安全性降低的问题。

                CBC模式下,因为IV参数的随机性,对于同一份明文,每次生成的密文都不同。

        3、CFB模式

        CFB(Cipher feedback:密码反馈模式),与ECB、CBC只能够加密块数据不同,CFB能够将块密文转换成流密文。

        CFB的加密工作分为两部分,

        1.将一前段加密得到的密文再加密

        2.将第一步得到的数据与当前段的明文异或。

        4、OFB模式

        OFB(Output feedback:反馈模式),OFB是先用块加密器生成密钥流(keystream),再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文。

        OFB与CFB都非常适合对流数据进行加密,OFB由于加密解密都依赖前一段数据,所以加密与解密都不能并行。

三、AES算法的CBC模式和ECB模式的区别

        Java标准库提供的对称加密接口非常简单,使用时的编码总结:

        1、根据算法名称/工作模式/填充模式 获取Cipher实例;

        2、再根据算法名称初始化一个SecretKey实例,密钥必须是指定长度;

        3、使用SecretKey初始化Cipher实例,并设置加密/加密模式;

        4、传入明文或密文,得到密文或明文。

        下面我们具体来了解AES算法的CBC模式和ECB模式。

        1.ECB模式

//AES不变加密结果
public class AESEBCDemo {
	// AES + ECB
		public static void main(String[] args) throws GeneralSecurityException {
			// 原文:
			String message = "天生我材必有用飞流直下三千尺";
			System.out.println("Message(原始信息): " + message);

			// 128位密钥 = 16 bytes Key:
			byte[] key = "1234567890abcdef".getBytes();

			// 加密:
			byte[] data = message.getBytes();
			byte[] encrypted = encrypt(key, data);
			System.out.println("Encrypted(加密内容): " + Base64.getEncoder().encodeToString(encrypted));

			// 解密:
			byte[] decrypted = decrypt(key, encrypted);
			System.out.println("Decrypted(解密内容): " + new String(decrypted));
		}

		// 加密:
		public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
			// 创建密码对象,需要传入算法/工作模式/填充模式
			Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");

			// 根据key的字节内容,"恢复"秘钥对象
			SecretKey keyStr=new SecretKeySpec(key,"AES");
			// 初始化秘钥:设置加密模式ENCRYPT_
			cipher.init(cipher.ENCRYPT_MODE,keyStr);
			// 根据原始内容(字节),进行加密
			return cipher.doFinal(input);
		}

		// 解密:
		public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
			// 创建密码对象,需要传入算法/工作模式/填充模式
			Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
			// 根据key的字节内容,"恢复"秘钥对象
			SecretKey keyStr=new SecretKeySpec(key, "AES");
			// 初始化秘钥:设置解密模式DECRYPT_MODE
			cipher.init(cipher.DECRYPT_MODE,keyStr);
			// 根据原始内容(字节),进行解密
			return cipher.doFinal(input);
		}

}

        结果:

       2 、CBC模式

//AES可变加密结果(增加了随机性,同样的结果加密后不一样)
public class AESCBCDemo {
	//AES + CBC
		public static void main(String[] args) throws Exception {
	        // 原文:
	        String message = "金樽清酒斗十千,玉盘珍羞直万钱";
	        System.out.println("Message(原始信息): " + message);
	        
	        // 256位密钥 = 32 bytes Key:
	        byte[] key = "dfbdhfvnbv7678687hghjtj7fhjyuiy8".getBytes();
	        
	        // 加密:
	        byte[] data = message.getBytes();
	        byte[] encrypted = encrypt(key, data);
	        System.out.println("Encrypted(加密内容): " + 
	        		Base64.getEncoder().encodeToString(encrypted));
	        
	        // 解密:
	        byte[] decrypted = decrypt(key, encrypted);
	        System.out.println("Decrypted(解密内容): " +
	        		new String(decrypted));
	    }

	    // 加密:
	    public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
	        // 设置算法/工作模式CBC/填充
	    	Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
	    	// 恢复秘钥对象
	        SecretKey keyStr=new SecretKeySpec(key,"AES");
	        // CBC模式需要生成一个16 bytes的initialization vector:
	        SecureRandom sr=SecureRandom.getInstanceStrong();
	        byte[] iv=sr.generateSeed(16);
	        
	        //保存iv参数
	        IvParameterSpec ivs=new IvParameterSpec(iv);
	        // 初始化秘钥:操作模式、秘钥、IV参数
	        cipher.init(Cipher.ENCRYPT_MODE,keyStr,ivs);
	        // 加密
	        byte[] mw=cipher.doFinal(input);
	        // IV不需要保密,把IV和密文一起返回:
	        return join(iv,mw);
	    }

	    // 解密:
	    public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
	        // 把input分割成IV和密文:
	        byte[] iv=new byte[16];
	        byte[] mw=new byte[input.length-16];
	        
	        //实现复制操作
	        System.arraycopy(input, 0, iv, 0, 16);
	        System.arraycopy(input, 16, mw, 0, mw.length);
	        
	        // 解密:
	        Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
	        SecretKey keyStr=new SecretKeySpec(key, "AES");//秘钥
	        IvParameterSpec ivs=new IvParameterSpec(iv);
	        
	        // 初始化秘钥:操作模式、秘钥、IV参数
	        cipher.init(Cipher.DECRYPT_MODE, keyStr,ivs);
	        // 解密操作
	        return cipher.doFinal(mw);
	    }
	    
	    // 合并数组
	    public static byte[] join(byte[] bs1, byte[] bs2) {
	       byte[] merge=new byte[bs1.length+bs2.length];
	       System.arraycopy(bs1, 0, merge, 0, bs1.length);
	       System.arraycopy(bs2, 0, merge, bs1.length, bs2.length);
	       return merge;
	    }
	

}

结果:

        区别:

工作模式特点安全性
ECB模式相同的内容,一直得到固定的输出密文。
CBC模式相同的内容,每次得到不同的输出密文。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值