Java中的3DES
Java中的3DES
- 介绍
3DES或三重数据加密算法是一种对称密钥块密码算法,它将DES密码算法对每个数据块应用三次。
在本教程中,我们将学习如何在Java中创建3DES密钥并使用它们对字符串和文件进行加密和解密。
- 生成密钥
生成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);
- 加密字符串
现在我们准备加密简单的字符串值。让我们首先定义一个我们要处理的字符串:
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编码使消息更易读且更易于使用。
- 解密字符串
现在,让我们看看如何逆转加密过程并将消息解密回其原始形式。为此,我们需要一个新的_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);
- 处理文件
我们也可以加密整个文件。例如,让我们创建一个包含一些文本内容的临时文件:
String originalContent = "Secret Baeldung message";
Path tempFile = Files.createTempFile("temp", "txt");
writeString(tempFile, originalContent);
接下来,让我们将其内容转换为一个单一的字节数组:
byte[] fileBytes = Files.readAllBytes(tempFile);
现在,我们可以像处理字符串一样使用加密密钥:
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密钥以及如何使用它来加密和解密字符串和文件。
如常,所有源代码都可以在GitHub上找到。