目录
一、AES算法的描述
AES(Advanced Encryption Standard)高级加密标准,它是一种对称密钥加密算法,被广泛用于数据加密和保护领域。
AES算法具有以下特点:
- 安全性强:AES算法经过多次专家评估和全球广泛应用,被公认为安全可靠的加密算法。
- 效率高:AES算法的硬件和软件实现效率高,适用于各种平台和设备。
- 灵活性:AES算法支持不同的密钥长度,可以根据安全要求进行调整。
- 广泛适用:AES算法应用广泛,支持多种应用场景和领域的数据加密需求。
AES算法有多种加密模式,其中最常见的两种模式是 ECB(Electronic Codebook)和 CBC(Cipher Block Chaining),除了ECB和CBC,还有其他的AES加密模式,如CFB(Cipher Feedback)、OFB(Output Feedback)和CTR(Counter)等。这些模式具有不同的特点和适用场景,可以根据具体需求选择合适的加密模式。
二、AES算法的两种常见模式
1.ECB(电子密码本)模式
加密的内容相同生成的密文也是相同的,ECB模式会生成一个16字节的密钥,加密和解密仅使用同一个密钥。ECB模式适合简单的加密场景,不适合加密大量重复的内容,并且,由于它加密解密使用同一个密钥,且无别的安全措施,因此具有一定的安全隐患。
2.CBC(密码块链)模式
由于CBC模式下加入了初始向量(Initialization Vector,IV),因此相同的内容产生的密文也是不同的。CBC模式生成的密钥为32个字节,而IV参数则需要16个字节,安全系数高于EBC模式,并且CBC模式可以加密大量重复的内容。
三、AES算法两种模式的具体实现(Java)
1.ECB模式
实现步骤:
a. 创建一个Cipher对象来确定具体实现使用的算法 ;
b. 创建一个密钥对象待使用;
c. 初始化密钥,设置模式(加密模式ENCRYPT_MODE/解密模式DECRYPT_MODE);
d. 对初始内容进行最终加密/解密操作所需,并返回加密后的结果。
(实现过程仅供参考,逻辑不尽相同,但步骤一致)
// 加密:
public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
// 创建密码对象,需要传入算法/工作模式/填充模式
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// 根据key的字节内容,"恢复"秘钥对象
SecretKey keySep = new SecretKeySpec(key,"AES");
// 初始化秘钥:设置加密模式ENCRYPT_
cipher.init(Cipher.ENCRYPT_MODE, keySep);
// 根据原始内容(字节),进行加密
return cipher.doFinal(input);
}
// 解密:
public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
// 创建密码对象,需要传入算法/工作模式/填充模式
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// 根据key的字节内容,"恢复"秘钥对象
SecretKey keySep = new SecretKeySpec(key,"AES");
// 初始化秘钥:设置解密模式DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySep);
// 根据原始内容(字节),进行解密
return cipher.doFinal(input);
}
2.CBC模式
实现步骤:CBC模式的实现步骤与ECB模式基本一致,但由于CBC模式加了一个IV参数,因此在创建完密钥对象后,根据具体需求,通过某些方式生成自己需要的16个字节的IV参数。
// 加密:
public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
// 设置算法/工作模式CBC/填充
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 恢复秘钥对象
SecretKey keySec = 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参数对象
IvParameterSpec ivps = new IvParameterSpec(iv);
// 初始化秘钥:操作模式、秘钥、IV参数
cipher.init(Cipher.ENCRYPT_MODE, keySec,ivps);
// 加密
byte[] data = cipher.doFinal(input);
// IV不需要保密,把IV和密文一起返回:
return join(iv,data);
}
// 解密:
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);
System.arraycopy(input, 16, data, 0, data.length);
System.out.println(Arrays.toString(iv));
// 解密:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey keySec = new SecretKeySpec(key, "AES");
// 恢复IV
IvParameterSpec ivps = new IvParameterSpec(iv);
// 初始化秘钥:操作模式、秘钥、IV参数
cipher.init(Cipher.DECRYPT_MODE, keySec,ivps);
// 解密操作
return cipher.doFinal(data);
}
// 合并数组
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;
}