一、简介
3DES(三重数据加密算法)是一种对称密钥分组密码,它对每个数据块应用三次 DES 密码算法。
在本教程中,我们将学习如何 创建 3DES 密钥并使用它们在 Java 中加密和解密 String 和文件 。
2. 生成密钥
生成 3DES 密钥需要几个步骤。首先,我们需要生成一个用于加密解密过程的密钥。在我们的例子中,我们将使用由随机数字和字母构造的 24 字节密钥:
byte[] secretKey = "9mng65v8jf4lxn93nabf981m".getBytes();
请注意, 不应公开共享密钥 。
现在,我们将把密钥包装在 SecretKeySpec 中,并将其与所选算法结合起来:
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "TripleDES");
在我们的例子中,我们使用 TripleDES ,它是Java 安全标准算法之一。
我们应该提前生成的另一项是密钥的初始化向量 。我们将使用一个由随机数字和字母组成的 8 字节数组:
byte[] iv = "a76nb5h9".getBytes();
然后,我们将其包装在 IvParameterSpec 类中:
IvParameterSpec ivSpec = new IvParameterSpec(iv);
3. 加密 String
我们现在准备加密简单的 字符串 值。让我们首先定义一个我们将使用的 字符串 :
String secretMessage = "Baeldung secret message";
接下来, 我们需要一个用加密模式、密钥和我们之前生成的初始化向量初始化的 Cipher 对象 :
Cipher encryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
请注意,我们使用的是带有CBC和PKCS#5 填充方案的 TripleDES 算法。
使用 Cipher ,我们可以运行 doFinal 方法来加密我们的消息 。请注意,它仅适用于 字节 数组,因此我们需要首先转换 字符串 :
byte[] secretMessagesBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessagesBytes);
现在,我们的消息已成功加密。如果我们想将其存储在数据库中或通过REST API发送,则使用 Base64 字母表进行编码会更方便:
String encodedMessage = Base64.getEncoder().encodeToString(encryptedMessageBytes);
Base64 编码使消息更具可读性且更易于使用。
4. 解密 字符串
现在,让我们看看如何反转加密过程并将消息解密为其原始形式。为此, 我们需要一个新的 Cipher 实例,但这一次,我们将以解密模式初始化它 :
Cipher decryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
接下来,我们将运行 doFinal 方法:
byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
现在,我们将结果解码为 字符串 变量:
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
最后,我们可以通过将结果与初始值进行比较来验证结果,以确保解密过程正确执行:
Assertions.assertEquals(secretMessage, decryptedMessage);
5. 使用文件
我们也可以加密整个文件。例如,让我们创建一个包含一些文本内容的临时文件:
String originalContent = "Secret Baeldung message";
Path tempFile = Files.createTempFile("temp", "txt");
writeString(tempFile, originalContent);
接下来,让我们将其内容转换为单个字节数组:
byte[] fileBytes = Files.readAllBytes(tempFile);
现在,我们可以像使用 String 一样使用加密密码:
Cipher encryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encryptedFileBytes = encryptCipher.doFinal(fileBytes);
最后,让我们用新的加密数据覆盖文件内容:
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
stream.write(encryptedFileBytes);
}
解密过程看起来非常相似。唯一的区别是在解密模式下初始化的密码:
encryptedFileBytes = Files.readAllBytes(tempFile);
Cipher decryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decryptedFileBytes = decryptCipher.doFinal(encryptedFileBytes);
再次,让我们用解密的数据覆盖文件内容:
try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
stream.write(decryptedFileBytes);
}
最后一步,我们可以验证文件内容是否与原始值匹配:
String fileContent = readString(tempFile);
Assertions.assertEquals(originalContent, fileContent);
六、总结
在本文中,我们学习了如何在 Java 中创建 3DES 密钥以及如何使用它来加密和解密 String 和文件。
与往常一样,所有源代码都可以在 GitHub 上获取。