1. Introduction
Jasypt (Java Simplified Encryption) Spring Boot provides utilities for encrypting property sources in Boot applications.
In this article, we’ll discuss how we can add jasypt-spring-boot‘s support and use it.
For more information on using Jasypt as a framework for encryption, take a look at our Introduction to Jasypt here.
2. Why Jasypt?
Whenever we need to store sensitive information in the configuration file – that means we’re essentially making that information vulnerable; this includes any kind of sensitive information, such as credentials, but certainly a lot more than that.
By using Jasypt, we can provide encryption for the property file attributes and our application will do the job of decrypting it and retrieving the original value.
3. Ways to Use JASYPT with Spring Boot
Let’s discuss the different ways to use Jasypt with Spring Boot.
3.1. Using jasypt-spring-boot-starter
We need to add a single dependency to our project:
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>
Maven Central has the latest version of the jasypt-spring-boot-starter.
Let’s now encrypt the text “Password@1” with secret key “password” and add it to the encrypted.properties:
encrypted.property=ENC(uTSqb9grs1+vUv3iN8lItC0kl65lMG+8)
And let’s define a configuration class AppConfigForJasyptStarter – to specify the encrypted.properties file as a PropertySource :
@Configuration @PropertySource("encrypted.properties") public class AppConfigForJasyptStarter { }
Now, we’ll write a service bean PropertyServiceForJasyptStarter to retrieve the values from the encrypted.properties. The decrypted value can be retrieved using the @Value annotation or the getProperty() method of Environment class:
@Service public class PropertyServiceForJasyptStarter { @Value("${encrypted.property}") private String property; public String getProperty() { return property; } public String getPasswordUsingEnvironment(Environment environment) { return environment.getProperty("encrypted.property"); } }
Finally, using the above service class and setting the secret key which we used for encryption, we can easily retrieve the decrypted password and use in our application:
@Test public void whenDecryptedPasswordNeeded_GetFromService() { System.setProperty("jasypt.encryptor.password", "password"); PropertyServiceForJasyptStarter service = appCtx .getBean(PropertyServiceForJasyptStarter.class); assertEquals("Password@1", service.getProperty()); Environment environment = appCtx.getBean(Environment.class); assertEquals( "Password@1", service.getPasswordUsingEnvironment(environment)); }
3.2. Using jasypt-spring-boot
For projects not using @SpringBootApplication or @EnableAutoConfiguration, we can use the jasypt-spring-boot dependency directly:
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot</artifactId> <version>2.0.0</version> </dependency>
Simillarly, let’s encrypt the text “Password@2” with secret key “password” and add it to the encryptedv2.properties:
encryptedv2.property=ENC(dQWokHUXXFe+OqXRZYWu22BpXoRZ0Drt)
And let’s have a new configuration class for jasypt-spring-boot dependency.
Here, we need to add the annotation @EncryptablePropertySource :
@Configuration @EncryptablePropertySource("encryptedv2.properties") public class AppConfigForJasyptSimple { }
Also, a new PropertyServiceForJasyptSimple bean to return encryptedv2.properties is defined:
@Service public class PropertyServiceForJasyptSimple { @Value("${encryptedv2.property}") private String property; public String getProperty() { return property; } }
Finally, using the above service class and setting the secret key which we used for encryption, we can easily retrieve the encryptedv2.property:
@Test public void whenDecryptedPasswordNeeded_GetFromService() { System.setProperty("jasypt.encryptor.password", "password"); PropertyServiceForJasyptSimple service = appCtx .getBean(PropertyServiceForJasyptSimple.class); assertEquals("Password@2", service.getProperty()); }
3.3. Using Custom JASYPT Encryptor
The encryptors defined in section 3.1. and 3.2. are constructed with the default configuration values.
However, let’s go and define our own Jasypt encryptor and try to use for our application.
S0, the custom encryptor bean will look like:
@Bean(name = "encryptorBean") public StringEncryptor stringEncryptor() { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); SimpleStringPBEConfig config = new SimpleStringPBEConfig(); config.setPassword("password"); config.setAlgorithm("PBEWithMD5AndDES"); config.setKeyObtentionIterations("1000"); config.setPoolSize("1"); config.setProviderName("SunJCE"); config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); config.setStringOutputType("base64"); encryptor.setConfig(config); return encryptor; }
Furthermore, we can modify all the properties for the SimpleStringPBEConfig.
Also, we need to add a property “jasypt.encryptor.bean” to our application.properties, so that Spring Boot knows which Custom Encryptor it should use.
For example, we add the custom text “Password@3” encrypted with secret key “password” in the application.properties:
jasypt.encryptor.bean=encryptorBean encryptedv3.property=ENC(askygdq8PHapYFnlX6WsTwZZOxWInq+i)
Once we set it, we can easily get the encryptedv3.property from the Spring’s Environment:
@Test public void whenConfiguredExcryptorUsed_ReturnCustomEncryptor() { Environment environment = appCtx.getBean(Environment.class); assertEquals( "Password@3", environment.getProperty("encryptedv3.property")); }
4. Conclusion
By using Jasypt we can provide additional security for the data that application handles.
It enables us to focus more on the core of our application and can also be used to provide custom encryption if required.
As always, the complete code for this example is available over on Github.