Spring Boot Password Encryption Using Jasypt

Password Encryption with Jasypt

Keeping sensitive data secure is essential, but it isn’t that easy in today’s world. If you are using the Spring Boot application and want to encrypt your credentials, such as DB passwords, server information, or personal data then the simplest way is to use Jasypt.

What is Jasypt?

Jasypt (Java Simplified Encryption) is a Java library that provides utilities for encrypting user-sensitive information. Jasypt is easy to set up, there is no need for you to have an in-depth understanding of cryptography. You can use Jasypt in a few simple steps. It is recommended to go with the default configuration but Jasypt does offer some customizations also.

Steps To Add Encryption Using Jasypt

  • Add jasypt-spring-boot-starter maven dependency in the pom.xml,
  • Add annotation in the Spring Boot Application main Configuration class,
  • Select a secret key to be used for encryption and decryption,
  • Encrypting single string value,
  • Encrypting all values in the application.properties file,
  • Run the application.

Let’s continue and do each of these steps one by one.

1. Adding Jasypt Maven Dependency

The simplest way of adding Jasypt to your project is by using Maven.

In the pom.xml file, add maven dependency, which can be found in Maven Repository. You can specify the version you are using in the version tag <version>YOUR_VERSION</version>.

Jasypt Maven Dependency for Spring Boot

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

Jasypt Maven Plugin

If you want to simplify the encryption and decryption process, then you can add the jasypt-maven-plugin in the same pom.xml file in the plugins section. This plugin allows the encryption and decryption of property files compatible with the Jasypt Spring Boot extension. You can read more about it here.

<plugin>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-maven-plugin</artifactId>
    <version>3.0.3</version>
</plugin>

The jasypt-maven-plugin is added to your project’s build setup to automate the encryption and decryption of property values during the build process. This can be particularly useful in a development environment where you need to encrypt sensitive data before deploying your application or when you need to decrypt values for troubleshooting without having to do these tasks manually.

pom.xml example

Below is an example of my pom.xml with the jasypt-spring-boot-starter dependency and with the jasypt-maven-plugin.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>Jasypt</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Jasypt</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.github.ulisesbocchio</groupId>
                <artifactId>jasypt-maven-plugin</artifactId>
                <version>3.0.3</version>
            </plugin>
        </plugins>
    </build>

</project>

2. Adding the @EnableEncryptableProperties Annotation

The @EnableEncryptableProperties annotation is used to activate the encryption and decryption features provided by Jasypt in your Spring Boot application. When you add this annotation to your main application class or any configuration class, it tells Spring Boot to process certain properties as encrypted and to use Jasypt to decrypt them before using them in the application.

Add @EnableEncryptableProperties annotation to the main application class.

package com.javajasypt.crud.example;

import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
...


@SpringBootApplication
@EnableEncryptableProperties
public class MyApplication {
    public static void main (String[] args) { 
    ...
}
}

3. Configure the Secret Key

The secret key is used to encrypt the credentials, and later the same key is used to decrypt them. You can choose any value of the secret key. For example “Butterfly”. Just remember that it is case-sensitive.

To configure the secret key add the following property to the application.properties file of your Spring Boot application.

jasypt.encryptor.password=theKey

Please note that the value “theKey” in my case is just an example. Choose a different value for your application. It can be a longer alpha-numeric string of characters. For example:

jasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z

The value of this property will be used to encrypt and decrypt sensitive information.

4. Manually Encrypting & Decrypting Configuration Properties with Jasypt

Let’s add a couple of sensitive configuration properties that we want to encrypt. I will add the following two properties to my application.properties file.

spring.datasource.username = myusername
spring.datasource.password = mypassword

So at this moment, my application.properties file will have three configuration properties:

spring.datasource.username = myusername
spring.datasource.password = mypassword
jasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z

Next, I will save changes and will open a new terminal window. In the terminal window, change the current directory to the home folder of your Spring Boot application. If you list files in this directory, you should see the pom.xml file.

Then, run the following command to encrypt configuration properties.

mvn jasypt:encrypt-value -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z -Djasypt.plugin.value="myusername"

Here’s a breakdown of the command:

  1. mvn: This is the command-line tool used to execute Maven commands.
  2. jasypt:encrypt-value: This is specifying the goal to encrypt a value using Jasypt.
  3. -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z: This is setting the encryption password that Jasypt will use to encrypt the value. The -D flag is used to pass system properties to the JVM, in this case, setting the jasypt.encryptor.password property to the specified value.
  4. -Djasypt.plugin.value="myusername": This is specifying the value to be encrypted. Again, the -D flag is used to pass a system property to the JVM, in this case, setting the jasypt.plugin.value property to "myusername".

When you run this command, the jasypt-maven-plugin will use Jasypt to encrypt the value "myusername" using the password 4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z. The encrypted value will then be output to the console. This encrypted value can then be used in your application’s configuration files, ensuring that the plaintext "myusername" is not exposed.

Now hit enter. You will see this will run and just above the BUILD SUCCESS line you will find the encrypted text within the bracket of the word ENC() as follows

Jasypt

You need to copy this whole text including ENC and parathesis and then paste it in place of the original property value in the application.properties file. Once you do it, your application.properties file should look similar to this:

spring.datasource.username = ENC(6v1iIWEAhlvDsliXOjdF7jNA2a8yHigexINnQzrj8Vqbce+5CTCy0euXK0qEuruv)
spring.datasource.password = mypassword
jasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z

I will run the encrypt command one more time to encrypt the value of the password configuration property.

mvn jasypt:encrypt-value -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z -Djasypt.plugin.value="mypassword"

Once “mypassword” is ecnrypted and I copied the encrypted value to the application.properties file, it looks like this:

spring.datasource.username = ENC(6v1iIWEAhlvDsliXOjdF7jNA2a8yHigexINnQzrj8Vqbce+5CTCy0euXK0qEuruv)
spring.datasource.password = ENC(6MmYBlbRcXoZmiNQqUuqZB4jChA+5NqEPTeoD/EHXOS383K+PgcDdalSVfJ+IhMR)
jasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z

5. Automatically Encrypting Configuration Properties with Jasypt

If you want to encrypt the username and password in application.properties files without manually entering the encrypted text then follow these steps.

Suppose your original code looks like this

spring.datasource.username = username
spring.datasource.password = password

Now wrap the values you need to be encrypted inside DEC() parenthesis as follows

spring.datasource.username = DEC(username)
spring.datasource.password = DEC(password)

Open the command prompt in the same directory and type

mvn jasypt:encrypt -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z -Djasypt.plugin.path="file:src/main/resources/application.properties"

When you will run this command it will automatically replace the DEC() placeholder with ENC() and the encrypted text in between, as follow

spring.datasource.username = ENC(srFjPLFU+IawCD4QQSFORULndGQ1QZx7FRQ3pNNKFi7W/9OqxtWd9MdrvrpAxhKo)
spring.datasource.password = ENC(1YkUDlreKjSMQyFJ0zcUY/XQLmQdrghXQp1OjTPMiYXnra/EBDiWZoZugioj5UHY)

6. Manually Decrypting Encrypted Values

To manually decrypt configuration properties encrypted with Jasypt, I will run the mvn jasypt:decrypt-value command. For example:

mvn jasypt:decrypt-value -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z -Djasypt.plugin.value="1YkUDlreKjSMQyFJ0zcUY/XQLmQdrghXQp1OjTPMiYXnra/EBDiWZoZugioj5UHY"

Here’s a breakdown of the command:

  1. mvn: This is the Maven command-line tool.
  2. jasypt:decrypt-value: This is the Maven goal to decrypt a value using Jasypt.
  3. -Djasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z: This is the password used for decryption, which should be the same as the one used for encryption.
  4. -Djasypt.plugin.value="1YkUDlreKjSMQyFJ0zcUY/XQLmQdrghXQp1OjTPMiYXnra/EBDiWZoZugioj5UHY": This is the encrypted value that you want to decrypt.

7. Decrypting Configuration Properties in Spring Boot Application

In this section, I will explain how encrypted configuration properties get decrypted in a Spring Boot application using the code snippet provided.

Activating Encryption/Decryption Features

First, I need to add the @EnableEncryptableProperties annotation to my Spring Boot application class. This annotation activates Jasypt’s property encryption/decryption features within the application. This is a necessary step to tell Spring Boot to process certain properties as encrypted and use Jasypt to decrypt them before they are used in the application.

@EnableEncryptableProperties
@SpringBootApplication
public class JasyptApplication {
    ...
}

Reading Configuration Properties

Next, to read configuration properties from my application.properties or application.yml file, I use the @Value annotation.

The application.properties of my Spring Boot application has the following configuration properties:

spring.datasource.username = ENC(srFjPLFU+IawCD4QQSFORULndGQ1QZx7FRQ3pNNKFi7W/9OqxtWd9MdrvrpAxhKo)
spring.datasource.password = ENC(1YkUDlreKjSMQyFJ0zcUY/XQLmQdrghXQp1OjTPMiYXnra/EBDiWZoZugioj5UHY)
jasypt.encryptor.password=4iSPcV2oeTBVf8BEoXbsSM84gIID7p29z

Notice that the username and the password properties are encrypted. So it is these two properties that I am going to read and decrypt in my application code.

In the provided code, I’m reading the spring.datasource.username and spring.datasource.password properties and assigning their values to the username and password fields respectively.

@Value("${spring.datasource.username}")
private String username;

@Value("${spring.datasource.password}")
private String password;

Decrypting Configuration Properties

Now, when my Spring Boot application starts up, because I have added the @EnableEncryptableProperties annotation, Jasypt automatically decrypts the spring.datasource.username and spring.datasource.password properties before assigning their values to the username and password fields. The decryption is done using the encryption password that is configured in the jasypt.encryptor.password property.

Displaying Decrypted Configuration Properties (Optional)

To display the decrypted configuration properties, I use a method annotated with @PostConstruct. This method is executed after the Spring context is initialized and the properties are decrypted. It’s important to note that this step is only for displaying the decrypted values. The @PostConstruct block is absolutely optional and does not have anything to do with the decryption process. I have added this code snippet for demonstration purposes only. In real application, you will never display descrypted values of sensitive information. So don’t do it.

How to Secure jasypt.encryptor.password?

Storing the encryption password (jasypt.encryptor.password) within the same application.properties file that contains encrypted properties can introduce a security risk. It’s similar to leaving a key to a safe next to the safe itself.

In this section, I will explain various methods to secure the jasypt.encryptor.password.

Environment Variables

One of the secure ways to handle jasypt.encryptor.password is to set it as an environment variable on the server where your Spring Boot application is running. Environment variables are a set of dynamic named values that can affect the way running processes will behave on a computer. They are part of the environment in which a process runs. By placing jasypt.encryptor.password in an environment variable, you keep it outside of your application’s code and configuration files, which is a good security practice.

To set an environment variable, you can use the export command in Unix/Linux systems or the set command in Windows systems. Here is how you can do it:

On Mac/Unix

export JASYPT_ENCRYPTOR_PASSWORD=yourpassword

On Windows

set JASYPT_ENCRYPTOR_PASSWORD=yourpassword

Now, when you run your Spring Boot application, Jasypt will automatically look for the jasypt.encryptor.password property in the environment variables and use it for encryption and decryption tasks. There is no need to read this property value in your Java code explicitly; Jasypt will handle it for you.

This method ensures that the encryption password is not hard-coded in your application or stored in version control, which is crucial for maintaining the security of your encrypted configuration properties.

Command Line Arguments

Instead of keeping the Jasypt password encryptor value in the application.properties file, you can pass it as a command line argument while starting your Spring Boot application. This method also ensures that the password isn’t hard-coded in the project files.

java -jar your-app.jar --jasypt.encryptor.password=yourpassword

Using External Configuration File

You can keep the jasypt.encryptor.password in an external configuration file outside your project. This file should be located in a secure directory with restricted access. When starting your application, you can tell it which configuration file to use by passing it as a command line argument. Here is an example:

java -jar your-app.jar --spring.config.location=file:/etc/secure-folder/application.properties

Spring Cloud Config Server

You can also use the Spring Cloud Config server to manage the jasypt.encryptor.password along with other application configurations in a centralized and secure manner. To learn more, check out other Spring Cloud Config server tutorials.

Cloud Provider’s Secret Management

If your application is hosted on a cloud platform, you can leverage the cloud provider’s secret management tools to securely handle the jasypt.encryptor.password. For example, AWS has the Secrets Manager, and GCP has the Secret Manager.

Conclusion

I hope this tutorial was helpful for you.

To learn more about building Spring Boot applications, you can check Spring Boot tutorials page or Spring Boot video tutorials page.

Happy learning!