Spring Boot uses the properties file, and at least by default, the passwords are in plain text. Is it possible to somehow hide/decrypt these?
7 Answers
You can use Jasypt to encrypt properties, so you could have your property like this:
db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)
Jasypt allows you to encrypt your properties using different algorithms, once you get the encrypted property you put inside the ENC(...)
. For instance, you can encrypt this way through Jasypt using the terminal:
encrypted-pwd$ java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: contactspassword
password: supersecretz
----OUTPUT----------------------
XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=
To easily configure it with Spring Boot you can use its starter jasypt-spring-boot-starter with group ID com.github.ulisesbocchio
Keep in mind, that you will need to start your application using the same password you used to encrypt the properties. So, you can start your app this way:
mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
Or using the environment variable (thanks to spring boot relaxed binding):
export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run
You can check below link for more details:
https://www.north-47.com/knowledge-base/spring-boot-password-encryption-with-jasypt/
To use your encrypted properties in your app just use it as usual, use either method you like (Spring Boot wires the magic, anyway the property must be of course in the classpath):
Using @Value
annotation
@Value("${db.password}")
private String password;
Or using Environment
@Autowired
private Environment environment;
public void doSomething(Environment env) {
System.out.println(env.getProperty("db.password"));
}
Update: for production environment, to avoid exposing the password in the command line, since you can query the processes with ps
, previous commands with history
, etc etc. You could:
Create a script like this:
touch setEnv.sh
Edit
setEnv.sh
to export theJASYPT_ENCRYPTOR_PASSWORD
variable#!/bin/bash
export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
Execute the file with
. setEnv.sh
Run the app in background with
mvn spring-boot:run &
Delete the file
setEnv.sh
Unset the previous environment variable with:
unset JASYPT_ENCRYPTOR_PASSWORD

- 355
- 3
- 11

- 30,085
- 15
- 87
- 123
-
2Could you please explain more in details using gradle @Frerica Piazza – testuser Jan 10 '17 at 12:30
-
It is not clear about using with maven. you pass some property and what further? Where property file? how to ise this value in code? – gstackoverflow Oct 02 '17 at 16:03
-
@gstackoverflow, the question is related to encryption/decryption and it's tagged with spring boot, the intention was to explain encryption stuffs not property usage. Anyway, I can edit this answer to give you more details. In the meantime, Spring uses this totally transparent, just inject the propertyes with `@Values("db.password")`. For "where" it is just the classpath. "What further"... nothing, spring boot does all the magic automatically – Federico Piazza Oct 02 '17 at 17:18
-
I was looking also for a solution to hide my passwords from the properties file and I found the above solution/tool to be very interesting. But, I had once a security issue in a project where passwords were visually exposed on a Linux OS when using the "ps" command (show process list). The whole commandline was displayed in the process list, that is the java commandline including "-DpwdName=pwd" property. Has anyone solved this problem? IBM has a workaround for this issue by letting you define JVM properties in a file and then let the JVM fetch the values without exposing them in the cmdline. – user2120188 Oct 10 '18 at 09:18
-
@user2120188 you can sort out this in different ways, for instance you can create a bash script named `setPass.sh` containing the `export` of your environment variable. So, then you just execute your script. Spring boot allows reading system properties as well as environment variables, and that's all you won't have the password in the shell history – Federico Piazza Oct 10 '18 at 14:26
-
Passing the password via "mvn -D..." does not work for me ("req. enc. configuration property jasypt.encryptor.pasword missing"). However, setting it in the application.yml works. Any thoughts? – Big X Oct 26 '18 at 07:24
-
"mvn spring-boot:run -Dspring-boot.run.arguments=--jasypt.encryptor.password=xxx" works! – Big X Oct 26 '18 at 07:33
-
@BigX that is not safe since whoever login in and run the `history` command will see your password – Federico Piazza Oct 26 '18 at 14:21
-
@FedericoPiazza but this also applies to your very similar command "mvn -Djasypt.encryptor.password=supersecretz spring-boot:run". For security you could run it on a Jenkins e.g. using credentials without exposing the password. – Big X Oct 29 '18 at 13:10
-
2@FedericoPiazza Isn't `mvn -Djasypt.encryptor.password=supersecretz spring-boot:run` going to show up in the `ps` output, exposing the password? – Srki Rakic Dec 27 '18 at 22:17
-
1@SrkiRakic yes, of course. This is just for development, if you want it for production you should use environment variables. Spring boot allows you to use `JASYPT_ENCRYPTOR_PASSWORD` – Federico Piazza Dec 28 '18 at 11:33
-
1haha and how does it get into environment variables? Probably from another file like service difinition :D Also jasypt is outdated when it comes to password derivation so make sure to use totally random 32 character password – Roman Plášil Mar 07 '19 at 03:35
-
@FedericoPiazza Is it possible to encrypt entire YAML and use it in application? – Ashish Bhosle Nov 14 '19 at 13:25
-
@AshishBhosle you might be interested in using spring vault for your use case. I would recommend you to create a question with that. – Federico Piazza Nov 15 '19 at 14:12
-
@FedericoPiazza Thank you for the information. And I have created the a question for the same. – Ashish Bhosle Nov 18 '19 at 06:06
-
What is the `input=` parameter used for on the `jar ...` command line to generate the encryption key? Can it be anything, or does it reference some kind of variable? – Chris F Jan 13 '20 at 19:24
-
@ChrisF as shown in my answer `input` is the text that you want to encrypt. You can use whatever text you want. – Federico Piazza Jan 13 '20 at 20:07
-
@FedericoPiazza, I thought `supersecretz` is the p/w you wanted to encrypt. Or is that the p/w to be used by the application to decrypt the encrypted p/w? – Chris F Jan 13 '20 at 20:11
-
1@ChrisF I think you are misunderstanding how the encryption works. The `input="this is the text I want to encrypt"` and `password="this is the key used to encrypt the input"` – Federico Piazza Jan 13 '20 at 20:12
-
Be aware that the last commit to jasypt happened almost two years ago. There is also an open issue with a lot of critique about the encryption algorithms here: https://github.com/jasypt/jasypt/issues/31 – patrickuhlmlann Apr 05 '22 at 19:47
-
your url is a dead url – pixel Jan 29 '23 at 19:44
-
1@pixel I've updated the url, check again – Federico Piazza Jan 30 '23 at 13:26
-
@FedericoPiazza Thanks, I will take a look. But interestingly, I was able to get it working for the application; however, all my tests are failing with `Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: either 'jasypt.encryptor.password', one of ['jasypt.encryptor.private-key-string', 'jasypt.encryptor.private-key-location'] for asymmetric encryption, or one of ['jasypt.encryptor.gcm-secret-key-string', 'jasypt.encryptor.gcm-secret-key-location', 'jasypt.encryptor.gcm-secret-key-password'] for AES/GCM encryption must be provided for ...` – pixel Jan 30 '23 at 17:10
To the already proposed solutions I can add an option to configure an external Secrets Manager
such as Vault.
- Configure Vault Server
vault server -dev
(Only for DEV and not for PROD) - Write secrets
vault write secret/somename key1=value1 key2=value2
- Verify secrets
vault read secret/somename
Add the following dependency to your SpringBoot project:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
Add Vault config properties:
spring.cloud.vault.host=localhost
spring.cloud.vault.port=8200
spring.cloud.vault.scheme=http
spring.cloud.vault.authentication=token
spring.cloud.vault.token=${VAULT_TOKEN}
Pass VAULT_TOKEN
as an environment variable.
Refer to the documentation here.
There is a Spring Vault project which is also can be used for accessing, storing and revoking secrets.
Dependency:
<dependency>
<groupId>org.springframework.vault</groupId>
<artifactId>spring-vault-core</artifactId>
</dependency>
Configuring Vault Template:
@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {
@Override
public VaultEndpoint vaultEndpoint() {
return new VaultEndpoint();
}
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("…");
}
}
Inject and use VaultTemplate:
public class Example {
@Autowired
private VaultOperations operations;
public void writeSecrets(String userId, String password) {
Map<String, String> data = new HashMap<String, String>();
data.put("password", password);
operations.write(userId, data);
}
public Person readSecrets(String userId) {
VaultResponseSupport<Person> response = operations.read(userId, Person.class);
return response.getBody();
}
}
Use Vault PropertySource
:
@VaultPropertySource(value = "aws/creds/s3",
propertyNamePrefix = "aws."
renewal = Renewal.RENEW)
public class Config {
}
Usage example:
public class S3Client {
// inject the actual values
@Value("${aws.access_key}")
private String awsAccessKey;
@Value("${aws.secret_key}")
private String awsSecretKey;
public InputStream getFileFromS3(String filenname) {
// …
}
}

- 6,881
- 10
- 46
- 64
-
+1 for this solution. Using a system like vault / etcd (or any other) is the way to go. https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/ – Book Of Zeus Jan 30 '19 at 15:38
-
4-1 because this doesn't explain how the "master" key (VAULT_TOKEN) is secured. Where did the VAULT_TOKEN environment variable come from? How is it secured? Without protecting that key, the attacker can use it to retrieve the secrets from the vault using the code packaged in the Spring Boot jar. – corporatedrone Mar 28 '19 at 02:33
-
Also securing prod is the main issue. So, it has to be spoken here. Guidance for Dev/QA environments if fine. – sofs1 Aug 18 '19 at 00:41
-
This works when there are many passwords. It works for one password to connect but its funny to say put the vault password in the environment so you don't have to put the other password in the same environment. – Lee Meador Sep 30 '19 at 21:04
-
1
UPDATE: I noticed folks down-voting this, so I have to say that although this is not an ideal solution, but this works and acceptable in some use-cases. Cloudfoundry uses Environment variables to inject credentials when a Service is binded to an application. More info https://docs.cloudfoundry.org/devguide/services/application-binding.html
And also if your system is not shared, then for local development this is also acceptable. Of course, the more safe and secure way is explained in Answer by @J-Alex.
Answer:
If you want to hide your passwords then the easiest solution is to use Environment variables in application.properties
file or directly in your code.
In application.properties
:
mypassword=${password}
Then in your configuration class:
@Autowired
private Environment environment;
[...]//Inside a method
System.out.println(environment.getProperty("mypassword"));
In your configuration
class:
@Value("${password}")
private String herokuPath;
[...]//Inside a method
System.out.println(herokuPath);
Note: You might have to restart after setting the environment variable. For windows:
Refer this Documentation for more info.

- 2,304
- 15
- 30
-
31I do not think setting the master password in the environment vars is such a good idea. The password is now more exposed than necessary. Providing it a startup as shown by Federico is less exposed and more "secure" than setting it in the environment. – Jaavaaan Sep 14 '16 at 06:11
-
Yaa, its not if you are using shared computer. But if you are the only administrator of your computer then no other user can see the env vars. I answered the hiding part and the easier one. But yes, I agree Federico's suggested method is way better. – Sanjay Rawat Sep 16 '16 at 05:30
-
Please see: https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/ – Book Of Zeus Jan 30 '19 at 15:38
-
@Jaavaaan providing JASYPT_ENCRYPTOR_PASSWORD in environment variable to decode db password is equally insecure as this answer. – m1ld Aug 18 '21 at 21:18
-
@Jaavaaan Please read the *Update*. I've already mentioned that this isn't secure in all cases, but there are valid use-cases like CF. Also pointed to a better highly secure solution of using HashiCorp Vault. – Sanjay Rawat Aug 20 '21 at 11:15
-
Is running the spring boot application environment variables are safe? – Shashi Ranjan Sep 12 '22 at 14:07
Spring Cloud Config Server will allow this type of behavior. Using JCE you can setup a key on the server and use it to cipher the apps properties.
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html

- 4,073
- 3
- 27
- 47
In case you are using quite popular in Spring Boot environment Kubernetes (K8S) or OpenShift, there's a possibility to store and retrieve application properties on runtime. This technique called secrets. In your configuration yaml file for Kubernetes or OpenShift you declare variable and placeholder for it, and on K8S\OpenShift side declare actual value which corresponds to this placeholder. For implementation details, see: K8S: https://kubernetes.io/docs/concepts/configuration/secret/ OpenShift: https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html

- 3,790
- 1
- 19
- 30
In additional to the popular K8s, jasypt or vault solutions, there's also Karmahostage. It enables you to do:
@EncryptedValue("${application.secret}")
private String application;
It works the same way jasypt does, but encryption happens on a dedicated saas solution, with a more fine-grained ACL model attached to it.

- 921
- 7
- 10
My solution for hiding a DB-Password in Spring Boot apps application.properties is implemented here.
Scenario: some fake password is read from application.properties on start and saved in global Spring object ConfigurableEnvironment. In runtime it will be programmatically replaced with a real DB password. The real password will be read from another config file saved in a safe, project-external place.
Don't forget: call the the Bean from main class with:
@Autowired
private SchedUtilility utl;

- 355
- 3
- 11

- 151
- 1
- 5