Security Top

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security 5:

>> CHECK OUT THE COURSE

1. Introduction

3DES or Triple Data Encryption Algorithm is a symmetric-key block cipher that applies the DES cipher algorithm three times to each data block.

In this tutorial, we'll learn how to create 3DES keys and use them for encrypting and decrypting Strings and files in Java.

2. Generating Secret Key

Generating a 3DES secret key requires a couple of steps. First, we'll need to generate a secret key that will be used for the encryption-decryption process. In our case, we'll use a 24-byte key constructed from random numbers and letters:

byte[] secretKey = "9mng65v8jf4lxn93nabf981m".getBytes();

Note that a secret key shouldn't be shared publicly.

Now, we'll wrap our key in the SecretKeySpec combining it with a chosen algorithm:

SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "TripleDES");

In our case, we're using TripleDES, which is one of the Java Security Standard Algorithms.

Another item we should generate in advance is the Initialization Vector for our key. We'll use an 8-byte array of random numbers and letters:

byte[] iv = "a76nb5h9".getBytes();

And then, we'll wrap it in the IvParameterSpec class:

IvParameterSpec ivSpec = new IvParameterSpec(iv);

3. Encrypting Strings

We're now ready to encrypt simple String values. Let's first define a String that we'll work with:

String secretMessage = "Baeldung secret message";

Next, we'll need a Cipher object initialized with the encryption mode, secret key, and the initialization vector that we generated previously:

Cipher encryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);

Note that we're using the TripleDES algorithm with a CBC and a PKCS#5 padding scheme.

With the Cipher, we can run the doFinal method to encrypt our message. Note that it only works with a byte array, so we need to transform our String first:

byte[] secretMessagesBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessagesBytes);

Now, our message is successfully encrypted. If we'd like to store it in a database or send it via a REST API, it would be more convenient to encode it with the Base64 alphabet:

String encodedMessage = Base64.getEncoder().encodeToString(encryptedMessageBytes);

Base64 encoding makes the message more readable and easier to work with.

4. Decrypting Strings

Now, let's see how we can reverse the encryption process and decrypt the message to its original form. For this, we'll need a new Cipher instance, but this time, we'll initialize it in decryption mode:

Cipher decryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);

Next, we'll run the doFinal method:

byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);

Now, we'll decode the result to a String variable:

String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);

Finally, we can verify the results to make sure the decryption process performed correctly by comparing it to the initial value:

Assertions.assertEquals(secretMessage, decryptedMessage);

5. Working with Files

We can encrypt whole files as well. As an example, let's create a temp file with some text content:

String originalContent = "Secret Baeldung message";
Path tempFile = Files.createTempFile("temp", "txt");
writeString(tempFile, originalContent);

Next, let's transform its content into a single byte array:

byte[] fileBytes = Files.readAllBytes(tempFile);

Now, we can use the encryption cipher the same way we did with a String:

Cipher encryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encryptedFileBytes = encryptCipher.doFinal(fileBytes);

Finally, let's overwrite the file content with new, encrypted data:

try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
    stream.write(encryptedFileBytes);
}

The decryption process looks very similar. The only difference is a cipher initialized in decryption mode:

encryptedFileBytes = Files.readAllBytes(tempFile);
Cipher decryptCipher = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decryptedFileBytes = decryptCipher.doFinal(encryptedFileBytes);

Once again, let's overwrite the file content – this time, with the decrypted data:

try (FileOutputStream stream = new FileOutputStream(tempFile.toFile())) {
    stream.write(decryptedFileBytes);
}

As the last step, we can verify if the file content matches the original value:

String fileContent = readString(tempFile);
Assertions.assertEquals(originalContent, fileContent);

6. Summary

In this article, we've learned how to create a 3DES key in Java and how to use it to encrypt and decrypt Strings and files.

As always, all source code is available over on GitHub.

Security bottom

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security 5:

>> CHECK OUT THE COURSE
Security footer banner
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!