How to secure secrets and passwords in Springboot?
By: Sunil Singh
Tags: Application Security, Best Practices, Java

is your application exposing any secrets?

What?

Often we tend to store the secrets and keys unencrypted form in our application’s properties file.

When you’re building a Springboot App, you’ll define your spring application properties (a yaml file).

Consider that your application connects to a DB and the password of the db is “Topsecret@123”.

spring:

datasource:

password: Topsecret@123

For any of your profile (dev, staging, prod) you’re not expected to store the password in plain form.

So we’ll encrypt this password and store.

How?

lets see how we can do that…

We’ll use “jasypt — a java based encryption utility” to encrypt our password.

Add the below dependency to your projects pom file:

<dependency>

<groupId>com.github.ulisesbocchio</groupId>

<artifactId>jasypt-spring-boot-starter</artifactId>

<version>LATEST</version>

</dependency>

Once this is added a jar will be pulled into to your local mvn repository, which we’ll use to encrypt our db password.

JasyptPBEStringEncryptionCLI is the CLI interface to encrypt which takes the below arguments:

input : plain text you want to encrypt

password : a shared secret / passphrase you need to remember to encrypt/decrypt (in our case it makes more sense to have it specific to your deployment environment)

algorithm : encryption algorithm | allowed algorithms are — PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40

Now run the below command to encrypt the password:

java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=”Topsecret@123" password=dev-env-secret algorithm=PBEWITHMD5ANDDES

if everything goes well you should see an output of this sort:

----ENVIRONMENT-----------------



Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.181-b13







----ARGUMENTS-------------------



algorithm: PBEWITHMD5ANDDES

input: DkjwlJ@3932093dkjdk0129kd#

password: dev-env-secret







----OUTPUT----------------------



UAAeT+y19eRr4yhWOjLyMR2lacgjppmBItLRUQusGAfz9yvVrsxp9g==

Now take the OUTPUT in my case it is “UAAeT+y19eRr4yhWOjLyMR2lacgjppmBItLRUQusGAfz9yvVrsxp9g==”.

Now you can place this encrypted string in your properties in the below format

ENC(***your encrypted password goes here***)

Here’s now the properties file will look like:

spring:

datasource:

password: ENC(UAAeT+y19eRr4yhWOjLyMR2lacgjppmBItLRUQusGAfz9yvVrsxp9g==)

Springboot will decrypt automatically on boot-up when you execute your springboot application with the VM option “-Djasypt.encryptor.password=dev-env-secret”.

java -jar -Dapplication.properties=application.yaml -Djasypt.encryptor.password=ddev-env-secret springboot_app.jar

Advantages:

- You’ll never expose any passwords/secrets in the code base.

- Tomorrow by any chance if the code exposes to public repo, the risk of ready available secrets/passwords is reduced.

- You can exercise environment specific controls with it.

Alternative to the above is to make use of Amazon Service — Secrets Manager (Its like a central Vault). We can use the secrets manager to keep all the application level secrets and write deployment scripts to generate the properties files just before deployment to pull the secrets from secrets manager.