如何使用Java函数实现AES对称加密和解密?
Java 提供了许多种方式可以实现 AES 对称加密和解密。 在这篇文章中,我们将介绍以下步骤:
1. 使用Java Cipher类初始化加密算法。
2. 生成一个密钥并使用该密钥初始化加密算法。
3. 使用Java Cipher类将需要加密的明文转换为字节数组。
4. 加密这个字节数组。
5. 使用Java Cipher类将加密后的密文转换为Base64位编码。
6. 使用Java Cipher类将Base64位编码的字符串进行解码并转换为字节数组。
7. 使用Java Cipher类解密字节数组。
8. 将解密后的字节数组转换为字符串。
下面我们将按照上述步骤详细解释AES对称加密和解密的实现。
1. 使用Java Cipher类初始化加密算法。
首先,我们需要使用Java Cipher类实例化一个 AES 加密算法。我们需要指定加密模式、填充模式和加密算法。
Cipher.getInstance("AES/CBC/PKCS5Padding");
这里我们使用了“AES/CBC/PKCS5Padding”模式,其中:
AES是加密算法的名称。
CBC是加密模式,这种模式需要一个向量。
PKCS5Padding是填充模式,这种模式是一个标准的填充模式,允许明文的长度不足块长度的整数倍。
2. 生成一个密钥并使用该密钥初始化加密算法。
Java 提供了许多种生成密钥的方法,其中使用Java KeyGenerator类是一种简单的方式。
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
这段代码使用“AES”算法名称实例化一个 KeyGenerator对象,并且将其初始化为 256 位大小的 AES 密钥。
byte[] key = keyGenerator.generateKey().getEncoded();
这段代码生成一个 AES 密钥并且将其转换为字节数组。
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
这段代码使用字节数组初始化一个 SecretKeySpec 对象,它将被用来初始化 Cipher 对象。
3. 使用Java Cipher类将需要加密的明文转换为字节数组。
String message = "This is a secret message";
byte[] plainText = message.getBytes(StandardCharsets.UTF_8);
这段代码将字符串转换为一个字节数组。
4. 加密这个字节数组。
IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[16]);
这段代码创建了一个 16 字节的向量,它将被用来加密数据。
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encryptedText = cipher.doFinal(plainText);
这段代码使用 AES/CBC/PKCS5Padding 模式初始化 Cipher 对象,并且将之前生成的 SecretKeySpec 对象和 IvParameterSpec 对象传递给它。最后,使用 doFinal 方法对明文字节数组进行加密并生成加密后的字节数组。
5. 使用Java Cipher类将加密后的密文转换为Base64位编码。
Base64.Encoder encoder = Base64.getEncoder();
String base64EncodedText = encoder.encodeToString(encryptedText);
这段代码使用 Java Base64 类的编码器将加密后的字节数组转换为 Base64 位编码字符串。
6. 使用Java Cipher类将Base64位编码的字符串进行解码并转换为字节数组。
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedText = decoder.decode(base64EncodedText);
这段代码使用 Java Base64 类的解码器将字符串转换回字节数组。
7. 使用Java Cipher类解密字节数组。
IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[16]);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedText = cipher.doFinal(decodedText);
这段代码使用与加密相同的 AES/CBC/PKCS5Padding 模式初始化 Cipher 对象,并且将 SecretKeySpec 和 IvParameterSpec 对象传递给它,最后,使用 doFinal 方法对解码后的字节数组进行解密并生成解密后的字节数组。
8. 将解密后的字节数组转换为字符串。
String result = new String(decryptedText, StandardCharsets.UTF_8);
System.out.println(result);
这段代码使用解密后的字节数组生成字符串并将其打印出来。
完整的代码片段如下所示:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String message = "This is a secret message";
// 初始化Cipher对象
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 创建一个AES256位的密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
// 得到一个密钥并加密
byte[] key = keyGenerator.generateKey().getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
// 得到明文并加密
byte[] plainText = message.getBytes(StandardCharsets.UTF_8);
IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[16]);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encryptedText = cipher.doFinal(plainText);
// 对加密后的密文进行Base64编码
Base64.Encoder encoder = Base64.getEncoder();
String base64EncodedText = encoder.encodeToString(encryptedText);
// 对Base64编码的密文进行解码
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedText = decoder.decode(base64EncodedText);
// 对解码后的密文进行解密
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedText = cipher.doFinal(decodedText);
// 将解密后的明文转换为字符串
String result = new String(decryptedText, StandardCharsets.UTF_8);
System.out.println(result);
}
}
