How to encrypt secrets in a Spring boot application?

Charu Agarwal
Javarevisited
Published in
4 min readSep 24, 2021

--

More often we used to store our secrets in plain text variables in our application’s properties file, but this is not a good practice.

The reason why storing plain text secrets is not good practice?

If we store plain text secrets in our application, anyone who has access to our file system can access the password-protected resource, and also it makes an attacker’s job quite easy.

So, in order to protect our application and enhance its security, we need to use some encryption method or store our secrets somewhere in a vault or secret manager service such as in AWS.

How we can encrypt those?

We will take a simple example here, suppose you are having a spring boot application and you have stored your plain text DataBase credentials in application.yml(yaml file) or application.properties file like this:

application.yml

spring:
datasource:
url: jdbc:mysql://localhost:3306/cdr?useSSL=false
username: root
password: root123

Now, to encrypt the username and password strings, we can use Jasypt(Java Simplified Encryption) library here.

How Jasypt works?

Jasypt provides two ways of encryption: One-way encryption(without a private key) and Two-way encryption(with a private key)

It uses the default encryption algorithm: PBEWithMD5AndDES but it provides an option to use stronger encryption options too, such as: PBEWithMD5AndTripleDES.

There is a free Jasypt Online Encryption and Decryption tool which provides an option for one-way as well two-way (simple) encryption and decryption.

How to use Jasypt in Spring boot application?

If you have @SpringBootApplication or @EnableAutoConfiguration Auto Configuration annotations then you can simply add below starter dependency and plugin to your project’s pom.xml or build.gradle and the encryption properties will be enabled in the entire application:

Maven:

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

Gradle:

implementation group: ‘com.github.ulisesbocchio’, name: ‘jasypt-spring-boot-starter’, version: ‘3.0.4’implementation group: ‘com.github.ulisesbocchio’, name: ‘jasypt-maven-plugin’, version: ‘3.0.4’

If you don’t use @SpringBootApplication or @EnableAutoConfiguration Auto-Configuration annotations then instead of adding the above dependency add the below dependency to your project:

Maven:

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

Gradle:

implementation group: ‘com.github.ulisesbocchio’, name: ‘jasypt-spring-boot’, version: ‘3.0.4’

And then add @EnableEncryptableProperties to your configuration class:

@Configuration
@EnableEncryptableProperties
public class MyApplication {
...
}

Now, once you have added these dependencies just update your project so that these dependencies will be available in your maven/gradle repository.

To encrypt the credentials with Jasypt, just go to application.yml and add the below properties :

jasypt:
encryptor:
algorithm: PBEWithMD5AndTripleDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator

Along with this, you need to write your secret strings like DEC(secret_string), so that Jasypt understands that which strings need to be encrypted:

spring:
datasource:
url: jdbc:mysql://localhost:3306/cdr?useSSL=false
username: DEC(root)
password: DEC(root123)

And then just go to the terminal and run the below command in your project root folder where the pom.xml exists :

Note: If you have application.yml then you need to add the file path argument in command as below because Jasypt by default looks for application.properties file in the classpath

mvn jasypt:encrypt -Djasypt.plugin.path=”file:src/main/resources/application.yml” -Djasypt.encryptor.password=”secretkey”

If you are using application.properties then you can use below command:

mvn jasypt:encrypt -Djasypt.encryptor.password=”secretkey”

Note: jasypt.encryptor.password argument in this command is using private key here, using which the secrets will be encrypted.

Once you run this command and go to your application.properties or application.yml file, you will see your secrets have been encrypted…Voilà

Now, you can see these strings now have changed to something like this:

spring:
datasource:
username: ENC(zI0hID6ReXaLOMNaOPMWQg==)

But if you try to run this application now as your secrets have been encrypted, your application won’t run due to an error of DB connectivity.

Now.. think about how we can tell the application to use these secrets in decrypted form?

One solution that comes to our mind is to store the private key (which is used to encrypt our secrets) somewhere using which the secrets were encrypted, but that’s again not a good way to do that.

What we can do as an alternate is, either we can store it in the system or environment variables or again we need to store it in encrypted form.

Better way is to configure the private key somewhere either in system/environment variables, and for that we again need to store a variable in application.yml, which we will configure as our environment variable:

jasypt:
encryptor:
algorithm: PBEWithMD5AndTripleDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
password: ${JASYPT_ENCRYPTOR_PASSWORD}

To store this JASYPT_ENCRYPTOR_PASSWORD as an environment variable, go to terminal and run the command

vi ~/.bash_profile

and add the property there

export JASYPT_ENCRYPTOR_PASSWORD = secretkey

Save the file and exit and then source the profile using

source ~/.bash_profile

If you are using an IDE, you need to restart it to get the updated value from environment/system variables.

And now you are all set. If you will run your application it will start without any error.

Note: This article has focused on encryption within the entire spring boot application, but if you need to customize it only for some classes you can reference to the Jasypt Github repository here.

Other Java and Spring Boot Articles you may like

--

--

Charu Agarwal
Javarevisited

Senior Software Engineer at McKinsey & Company