Spring Boot: Encrypt Property Value in Properties File
Overview
During my experiences working with Java, there are must be cases that I have to use properties files in order to store configurable parameter. For example, folder location for storing temporary files or wsdl location if I need to invoke SOAP services. But sometimes, I need to store sensitive information, such as database password in the configuration file. Therefore, we need to encrypt property value for sensitive information, in order to make it harder for the attacker to compromise our system.
Use Case
For the use case, I want to encrypt property value with key variable.secret-var
in the property file. The encrypted value then will be decrypted during the runtime.
Step by Step
For this example, I will use spring boot as a baseline.
Spring boot can use two types of configuration files. One is application.properties and the other one is application.yml.
For this use case, I use the yml extension. However, the steps are similar
Step 1: Download Spring Boot Project
Go to spring initialzr page, fill package and artifact name. Since this project is intended for displaying the encrypted property value, leave empty for the rest then click generate project.
Step 2: Configure pom.xml
We need to add jasypt spring boot starter library into our pom, in order to use the their attributes in our properties or yaml file.
1 2 3 4 5 |
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>1.7</version> </dependency> |
Step 3: Configure Algorithm and Encryption Key
Put jasypt attributes in application.yml
1 2 3 4 |
jasypt: encryptor: algorithm: PBEWithMD5AndDES password: secretkey |
Step 4: Generate Encrypted Text
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
java -cp org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="RageAgainstTheMachine" password=secretkey algorithm=PBEWithMD5AndDES ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.25-b02 ----ARGUMENTS------------------- algorithm: PBEWithMD5AndDES input: RageAgainstTheMachine password: secretkey ----OUTPUT---------------------- VMAckVUvHhbiEpU1pG4JuFyc3WWR5CJ8FkRTmpcZoow= |
Note: you may get a different output since jasypt use salt mechanism.
Step 5: Set Encrypted Value
Then put the encrypted value into variable.secret-var
key in application.yml
file.
1 2 |
variable: secret-var: ENC(VMAckVUvHhbiEpU1pG4JuFyc3WWR5CJ8FkRTmpcZoow=) |
Note: the encrypted value is prefixed by ENC
word followed by bracket
Step 6: Create Spring Bean
After we finish with the configuration part, it is time to create the bean. All we need is create an instance variable, private modifier is better, and put @Value
annotation with variable.secret-var
key. Then we print the mySecretVar
variable.
1 2 3 4 5 6 7 8 9 10 11 12 |
@Component public class MyBean { @Value("${variable.secret-var}") private String mySecretVar; public void printVariable(){ System.out.println("============================================"); System.out.format("My secret variable is: %s\n", mySecretVar); System.out.println("============================================"); } } |
Step 7: Run the Program
Now we modify a little bit in the main class, in order to print the variable.
1 2 3 4 5 |
public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(JasyptApplication.class, args); MyBean bean = context.getBean(MyBean.class); bean.printVariable(); } |
And we will get output such as:
Conclusion
So, that is it. Now you can encrypt the variable value inside property file. However, maybe you are wondering, it would be non-sense if we put the encrypted variable and the jasypt configuration into one property file. For this cases, we can make separate property file between jasypt configuration and the encrypted value. The technique is using externalized configuration. But that would be out of scope for this post. I will try to bring it in the future.
Meanwhile, you can check all the code in my repository. Have a nice day!
What the different using application.properties or application.yml ?
Basically it will be no different. Spring boot will always look application.properties or application.yml file during the start up. One of the main different is on how the content inside file is structured. The application.properties file is using the key value meanwhile the application.yml is using YAML file structured.
For more detail examples, you can see on https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-use-yaml-for-external-properties
Hello there, I wonder if you ever made that tutorial about externalizing the configuration to hide the jasypt configuration? Thanks 🙂
In terms of externalizing jasypt config, I havent. What I have tried is putting the configuration (database configuration) outside java classpath. In other words, I put into external folder path (example the file location under /opt/config/myapps.properties). But the idea is similar, and in theory, it can be done as well.
I will try to create a branch from my repo, in order to test whether it works or not. Hopefully sooner 😀
Thanks a lot for the quick reply. Yes I would have to do that. I really wanted to create a ready for production jar file that I could move around. I can also do that but then I would have to start the app with a -Djasypt.encryptor.password=secretkey
I’m using this encryption for SSL
server:
port: 9999
context-path: /XYZ
ssl:
enabled: true
key-alias: ssl_alias
key-password: ENC(8NzIuKELUDi1zxOf8BOhrGViayD3hZ8j)
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES
password: secretkey
But when run the application I get the below error
java.lang.IllegalArgumentException: java.security.UnrecoverableKeyException: Cannot recover key
If I give normal text in the place of ENC(….) it’s working fine
Can you help in this regard.
I am sorry, I cannot help you much on this. This is a new information for me as well. Maybe you can share a little bit of your code in order to get more into your context?
I solved this issue this happened due to missing jasypt configuration
Hi,
Can you help in writing the external configuration of spring . How does it makes our jasypt configuration confidential?
Thanks,
Vijay
Hi Vijay,
I was able to achieve this with the help of this post. See my comment below for a full configuration. I am adding the secret to an environment variable.
https://github.com/ulisesbocchio/jasypt-spring-boot/issues/11#issuecomment-333134117
Hope this helps.
Wow.. that’s awesome.. Thank you Fred..
what package we need import PooledPBEStringEncryptor
As mentioned in documentation:
http://www.jasypt.org/api/jasypt/1.8/org/jasypt/encryption/pbe/PooledPBEStringEncryptor.html
When will you tell me why you are separating the files?
how safe is it to use below dependency. I am worried because its group id is of github. Is it ok to use?
com.github.ulisesbocchio
jasypt-spring-boot-starter
1.14
Honestly, you can see the source code there. So you can determine whether it is safe or not. But so far, I use it with no issue 🙂
If I want to store the encrypted password in the properties file without using Jasypt lib so is there any way to do the same?
I hardcoded the decrypted password in the application.properties file, and the jdbcTemplate got the db connection successfully.But I have to store the encrypted password in the application.properties file instead of the decrypted value.
How do I pass the decrypted value to the JdbcTemplate before it gets the db connection?
Thank you
algorithm: PBEWithMD5AndDES
Can i directly give SHA-256 instead of PBEWithMD5AndDES ?
algorithm: PBEWithMD5AndDES
Can i directly use SHA-256 instead of PBEWithMD5AndDES ?
here is the list of algorithms: http://www.jasypt.org/cli.html#Listing_algorithms
On side note, sha-256 is irreversible encryption. Meanwhile, we need to encrypt and decrypt the value (reversible)