Jasypt integration for Spring boot
Jasypt Spring Boot provides Encryption support for property sources in Spring Boot Applications.
There are 3 ways to integrate jasypt-spring-boot in your project:
- Simply adding the starter jar
jasypt-spring-boot-starterto your classpath if using@SpringBootApplicationor@EnableAutoConfigurationwill enable encryptable properties across the entire Spring Environment - Adding
jasypt-spring-bootto your classpath and adding@EnableEncryptablePropertiesto your main Configuration class to enable encryptable properties across the entire Spring Environment - Adding
jasypt-spring-bootto your classpath and declaring individual encryptable property sources with@EncrytablePropertySource
Update 7/18/2015: jasypt-spring-boot is now in Maven Central!
Use one of the following 3 methods (briefly explained above):
-
Simply add the starter jar dependency to your project if your Spring Boot application uses
@SpringBootApplicationor@EnableAutoConfigurationand encryptable properties will be enabled across the entire Spring Environment (This means any system property, environment property, command line argument, application.properties, yaml properties, and any other custom property sources can contain encrypted properties):<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>1.2</version> </dependency>
-
IF you don't use
@SpringBootApplicationor@EnableAutoConfigurationAuto Configuration annotations then add this dependency to your project and encryptable properties will be enabled across the entire Spring Environment (This means any system property, environment property, command line argument, application.properties, yaml properties, and any other custom property sources can contain encrypted properties):<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot</artifactId> <version>1.2</version> </dependency>
And then add
@EnableEncryptablePropertiesto you Configuration class. For instance:@Configuration @EnableEncryptableProperties public class MyApplication { ... }
-
IF you don't use
@SpringBootApplicationor@EnableAutoConfigurationAuto Configuration annotations and you don't want to enable encryptable properties across the entire Spring Environment, there's a third option. First add the following dependency to your project:<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot</artifactId> <version>1.2</version> </dependency>
And then add as many
@EncryptablePropertySourceannotations as you want in your Configuration files. Just like you do with Spring's@PropertySourceannotation. For instance:@Configuration @EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties", ignoreResourceNotFound = false) public class MyApplication { ... }
This will trigger some configuration to be loaded that basically does 2 things:
- It registers a Spring post processor that decorates all PropertySource objects contained in the Spring Environment so that thet are "encryption aware" and detect when properties are encrypted following jasypt's property convention.
- It defines a default
StringEncryptorthat can be configured through regular properties, system properties, or command line arguments.
When using METHODS 1 and 2 you can define encrypted properties in any of the PropertySource contained in the Environment. For instance, using the @PropertySource annotation:
@SpringBootApplication
@EnableEncryptableProperties
@PropertySource(name="EncryptedProperties", value = "classpath:encrypted.properties")
public class MyApplication {
...
}And your encrypted.properties file would look something like this:
secret.property=ENC(nrmZtkF7T0kjG/VodDvBw93Ct8EgjCA+)Now when you do environment.getProperty("secret.property") or use @Value("${secret.property}") what you get is the decrypted version of secret.property.
When using METHOD 3 (@EncryptablePropertySource) then you can access the encrypted properties the same way, the only difference is that you must put the properties in the resource that was declared within the @EncryptablePropertySource annotation so that the properties can be decrypted properly.
Jasypt uses an StringEncryptor to decrypt properties. For all 3 methods, if no custom StringEncryptor is found in the Spring Context, one is created automatically that can be configured through the following properties (System, properties file, command line arguments, environment variable, etc.):
| Key | Required | Default Value |
| jasypt.encryptor.password | True | - |
| jasypt.encryptor.algorithm | False | PBEWithMD5AndDES |
| jasypt.encryptor.keyObtentionIterations | False | 1000 |
| jasypt.encryptor.poolSize | False | 1 |
| jasypt.encryptor.providerName | False | SunJCE |
| jasypt.encryptor.saltGeneratorClassname | False | org.jasypt.salt.RandomSaltGenerator |
| jasypt.encryptor.stringOutputType | False | base64 |
| jasypt.encryptor.proxyPropertySources | False | false |
The only property required is the encryption password, the rest could be left to use default values. While all this properties could be declared in a properties file, the encryptor password should not be stored in a property file, it should rather be passed as system property, command line argument, or environment variable and as far as its name is jasypt.encryptor.password it'll work.
The last property, jasypt.encryptor.proxyPropertySources is used to indicate jasyp-spring-boot how property values are going to be intercepted for decryption. The default value, false uses custom wrapper implementations of PropertySource, EnumerablePropertySource, and MapPropertySource. When true is specified for this property, the interception mechanism will use CGLib proxies on each specific PropertySource implementation. This may be useful on some scenarios where the type of the original PropertySource must be preserved.
For custom configuration of the encryptor and the source of the encryptor password you can always define your own StringEncryptor bean in your Spring Context, and the default encryptor will be ignored. For instance:
@Bean
static 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;
}The jasypt-spring-boot-demo folder contains a working Spring Boot app example. The Demo app explicitly sets a System property with the encryption password before the app in runned. To have a little more realistic scenario try removing the line where the system property is set, build the app with maven, and the run:
java -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar --jasypt.encryptor.password=password
And you'll be passing the encryption password as a command line argument. Run it like this:
java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar
And you'll be passing the encryption password as a System property.