AES算法的ECB和CBC工作模式

目录

一、什么是AES算法

二、 AES算法的两种工作模式

1、ECB

2、CBC

总结:


一、什么是AES算法

        在之前的文章中,我了解了哈希算法加密,但是它只能用于加密后进行验证。而在互通信息时不仅需要加密也需要解密,这就需要使用对称加密算法,即使用同一个密钥进行加密和解密的算法,而AES算法就是现在最常用对称加密算法。

算法

密钥长度

工作模式

填充模式

DES

56/64

ECB/CBC/PCBC/CTR/...

NoPadding/PKCS5Padding/...

AES

128/192/256

ECB/CBC/PCBC/CTR/...

NoPadding/PKCS5Padding/PKCS7Padding/...

IDEA

128

ECB

PKCS5Padding/PKCS7Padding/...

        密钥长度直接决定加密强度,而工作模式和填充模式可以看成是对称加密算法的参数和格式选择。Java标准库提供的算法实现并不包括所有的工作模式和所有填充模式。最后,值得注意的是,DES算法由于密钥过短,可以在短时间内被暴力破解,所以现在已经不安全了。

二、 AES算法的两种工作模式

1、ECB

ECB模式是最简单的AES加密模式,它需要一个固定长度的密钥,固定的明文会生成固定的密文。在了解具体实现前,我们需要了解一下算法流程:

  1.  根据算法名称/工作模式/填充模式获取Cipher实例;
  2. 根据算法名称初始化一个SecretKey实例,密钥必须是指定长度;
  3. 使用SerectKey初始化Cipher实例,并设置加密或解密模式;
  4. 传入明文或密文,获得密文或明文。
// 加密:
	public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
		// 创建密码对象,需要传入算法/工作模式/填充模式
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

		// 根据key的字节内容,"恢复"秘钥对象
		SecretKey keySpec = new SecretKeySpec(key, "AES");

		// 初始化秘钥:设置加密模式ENCRYPT_
		cipher.init(Cipher.ENCRYPT_MODE, keySpec);

		// 根据原始内容(字节),进行加密
		return cipher.doFinal(input);
	}

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

小结:ECB工作模式是一种一对一的简单加密模式。

           init()方法进行密钥初始化操作,选择加密或解密。

          doFinal()方法对信息进行加密或解密操作。

2、CBC

        因为ECB工作模式的一对一方式安全性较低,所以,可选择需要一个随机数作为IV参数的CBC模式,这样对于同一份明文,每次生成的密文都不同安全性大大提升。

首先来了解一下加密操作:
 

 // 加密:
    public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        // 设置算法/工作模式CBC/填充
    	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    	// 恢复秘钥对象
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        // CBC模式需要生成一个16 bytes的initialization vector:
        SecureRandom sr = SecureRandom.getInstanceStrong();
        byte[] iv = sr.generateSeed(16);
        System.out.println("iv内容:" + Arrays.toString(iv));
        System.out.println("iv长度:" + iv.length);
        //随机数封装成参数对象
        IvParameterSpec ivps = new IvParameterSpec(iv);
        // 初始化秘钥:操作模式、秘钥、IV参数
        cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivps);
        // 加密
        byte[] data = cipher.doFinal(input);
        // IV不需要保密,把IV和密文一起返回:
        return join(iv,data);
    }

 在流程与方法名称上CBC与ECB并没有什么明显区别,但在init()方法的参数中和可以看到ivps参数,即iv参数对象,与密钥和原文一起加密。所以当我们解密时也需要相同的iv参数进行解密,所以需要我们将iv参数一并给需要解密的一方,所有调用join()方法及逆行拼接。

public static byte[] join(byte[] bs1, byte[] bs2) {
        byte[] r = new byte[bs1.length + bs2.length];
        System.arraycopy(bs1,0,r,0,bs1.length);
        System.arraycopy(bs2, 0, r, bs1.length, bs2.length);;
        return r;
    }

 解密操作:

// 解密:
    public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        // 把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);//密文
        // 解密:
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        IvParameterSpec ivps = new IvParameterSpec(iv);
        // 初始化秘钥:操作模式、秘钥、IV参数
        cipher.init(Cipher.DECRYPT_MODE,keySpec,ivps);
        // 解密操作
        return cipher.doFinal(data);
    }

因为加密后将IV参数和密文放在了一起,所以我们首先要进行字节数组的拆分,将两者分离开。

之后操作与加密操作并无区别,只需注意操作模式的选择即可。

注意:在我们进行数据合并时,应该将固定长度的iv参数放在数组前面,因为,不同的原始信息产生的密文是不同长度的。

总结:

AES算法是一种常用的对称加密算法。

ECB工作模式是一对一的简单加密方式,优点就是简单,缺点是安全性较低。

CBC工作模式则是需要一个iv参数的针对相同原始信息,可以生成不同密文相对更安全的模式。

你可能感兴趣的:(算法)