Hide passwords in application properties of Spring boot application - spring-boot

Whenever the question of hiding the fields like passwords in application properties file arises,the straight-forward answer is encrypt those details using jasypt or other encryption.
If you keep encrypted passwords and jasypt details in same file, how does that make sense? or may be keep them in different file..
Any other smarter way for this?

You're not supposed to save the encryption key in application.properties, after all you don't want it going to your repository. You have to provide the key to your application when you run it, either by typing it or by storing it somewhere on your server. Check this thread for examples.

Let's assume that you have gotten your passwords in a typical application.properties file. Using Jaspyt, you may encrypt as follows:
Maven setup.... Grab the latest spring boot starter Jasypt POM, use
com.github.ulisesbocchio as the group ID.
Create a tiny utility class (preferably outside your spring boot app) to encrypt your passwords; it's easy to use Jasypt's BasicTextEncryptor class ex:
BasicTextEncryptor pwdEncrypt = new BasicTextEncryptor();
pwdEncrypt.setPassword(your_secret_sauce)//whatever you use here will be needed in the properties file (more on that later)
String encoded = pwdEncrypt.encrypt(password_you_want_to_encrpyt);
The String encoded is PBE-encoded by default; grab that
In your properties file, make the following entries:
jasypt.encryptor.password=your_secret_sauce //used in your utility
password_entry_you_want_to_encrypt=ENC(encoded) //encoded grabbed from your utility class
I'll assume that you're annotating your main class with
#SpringBootApplication. Add the following annotations as well:
#EnableEncryptableProperties
#PropertySource(name="EncryptedProperties", value = "classpath:application.properties")

Use jasypt to encrypt properties in application.properties file.
it's usesPBEWithMD5AndDES for the encryption.
See:
https://github.com/ulisesbocchio/jasypt-spring-boot

Related

Using encrypted password for database connection in spring boot application through spring auto configuration

Trying to use encrypted database password to connect to database using spring auto configuration
I am using Spring auto configuration to connect to database. For that i added below properties in properties file:
spring.datasource.url=jdbc:oracle:thin:#ABCDE2D.com:1888:ABCDE2D1
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-oracle.jdbc.driver.OracleDriver
In my dao class, i have #Autowired NamedParameterJdbcTemplate and using it directly to get data from database.
Till here it is working fine.
Now i need to encrypt the password in properties file.
For that i did the below:
Added jasypt-spring-boot-starter in pom
Added spring.datasource.password=ENC(NoIv2c+WQYF3LenN0tDYPA==) in properties file
Added jasypt.encryptor.password=key in properties file
Now i am getting the below error:
Failed to bind properties under 'spring.datasource.password' to
java.lang.String:
Reason: Failed to bind properties under 'spring.datasource.password' to
java.lang.String
I'm providing some basic guide as follows.
You need to add following two parameters in to property file in order application to work properly. This is assuming you are encrypting using default encryption algorithm. If you are useing some other, then make sure to change it accordingly.
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndDES
You can refer to more details
https://nirmalbalasooriya.blogspot.com/2020/02/spring-boot-property-encryption-using.html
In my case I was giving wrong jasypt.encryptor.password.
For Example given below is properties I have set in my application.properties:
jasypt.encryptor.password=abc
instead abc I gave jasypt as my secret key while encrypting the password so the encripted password is wrong. Then it throwing this error.
Later I realised and found that the key is not correct.
Then gave the right key i.e., abc.Then it worked for me.
Silly mistake but it cost me 4 hours. Hope it will be useful for others.
If you are using jasypt dependency, make sure that:
spring.datasource.password = Enc
and
jasypt.encryptor.password = key
where Enc is encrypted password and key is the key which you used to generate the encrypted password.

Spring boot application properties load process change programatically to improve security

I have spring boot micro-service with database credentials define in the application properties.
spring.datasource.url=<<url>>
spring.datasource.username=<<username>>
spring.datasource.password=<<password>>
We do not use spring data source to create the connection manually. Only Spring create the database connection with JPA.(org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration)
We only provide the application properties, but spring create the connections automatically to use with the database connection pool.
Our requirement to enhance the security without using db properties in clear text. Two possible methods.
Encrypt the database credentials
Use the AWS secret manager. (then get the credential with the application load)
For the option1, jasypt can be used, since we are just providing the properties only and do not want to create the data source manually, how to do to understand by the spring framework is the problem. If better I can get some working sample or methods.
Regarding the option-2,
first we need to define secretName.
use the secertName and get the database credentials from AWS secret manager.
update the application.properties programatically to understand by spring framework. (I need to know this step)
I need to use either option1 and option2. Mentioned the issues with each option.
What you could do is use environment variables for your properties. You can use them like this:
spring.datasource.url=${SECRET_URL}
You could then retrieve these and start your Spring process using a ProcessBuilder. (Or set the variables any other way)
I have found the solution for my problem.
We need to define org.springframework.context.ApplicationListenerin spring.factories file. It should define the required application context listener like below.
org.springframework.context.ApplicationListener=com.sample.PropsLoader
PropsLoader class is like this.
public class PropsLoader implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
String appEnv = environment.getProperty("application.env");
//set new properties based on the application environment.
// calling other methods and depends on the enviornment and get the required value set
Properties props = new Properties();
props.put("new_property", "value");
environment.getPropertySources().addFirst(new PropertiesPropertySource("props", props));
}
}
spring.factories file should define under the resources package and META-INF
folder.
This will set the application context with new properties before loading any other beans.

jasypt encryption not working in spring boot

I want to do encryption for some sensitive data in application.properties file of spring boot application.
for that I have used jasypt-spring-boot-starter plugin .
also used #EnableEncryptableProperties tag on spring application.
I have encrypted access key for my database and written its encrypted value in the property file.
com.test.SharedAccessKey=ENC(vfQQ9veC1G+RV8BC0VA==)
also provided in property file
jasypt.encryptor.password=secretpassword
jasypt.encryptor.algorithm=PBEWithMD5AndDES
I am accessing this property in spring boot application as followes
#Value("${com.test.SharedAccessKey}")
public String shareAcessKey;
But logger.info(shareAcessKey) print as it is ENC(vfQQ9veC1G+RV8BC0VA==)
what I am missing in above , can anyone help.
Issue was resolved . I have done some configuration in my spring Configuration class #Configuration related to property file.
as set property place holder configure to setIgnoreUnresolvablePlaceholders
after removing above code . Jasypt password is got picked up.

What is the standard for PROD database password in the Springboot fat jar application connecting a database

I have a springboot application which connects to database, currently the database password is in plain text inside the application properties.
What is the standard for securely protecting password in PROD environment?
How to change the database password if the application password is inside the application properties which is built in as part of the JAR and especially when the application is live?
You could use jasypt to handle the encryption and then use Jasypt's Spring integration or this Jasypt Spring Boot Starter to wire it into Spring.
This will allow you to define an encrypted database password property, for example in application.properties e.g.
db.password=ENC(.....)
The other part of your question is:
How to change the database password if the application password is inside the application properties
You can do this by overring properties defined in your properties file with system properties. For example: -Ddb.password='....'. You could also define an additional properties source which is external to your JAR and can be edited at runtime. For example:
#PropertySources({
#PropertySource(value = "classpath:/**.properties"),
#PropertySource(value = "file:/some/external/directory/override.properties", ignoreResourceNotFound = true)
})
public class Application {
// ...
}
Creating the file /some/external/directory/override.properties and populating it with db.password=... would cause your application - on next restart - to use that property value.

Spring Boot Custom Properties - How to include externalize properties when class is not in the application context

It is hard to understand but for my application a required format. I have some custom libraries which are included at runtime and so they are not in the spring application context. To get apis from spring boot application I catched required apis and overhand this to my external classes.
To show an example:
HashValueService hashValueService
= (HashValueService) appContext.getBean("hashValueServiceImpl");
ServiceList srvList = new ServiceList();
srvList.setHashValueService(hashValueService);
In this way I'm able to get access to my database, which is in my application context.
I have a lot of properties distributed in the whole application. So I want to use the default application.properties to centralized often used properties in my application, like the keystore.
For that I edited application.properties with this line:
application.keystore=server.jks
But of course the usage of the Spring's #Value does show me a null for that attribute, because this class is not in my application context:
#Value("${application.keystore}")
private String keystore;
Do you have an idea to overhand this properties to this customer libraries? Maybe the creation of a new property file whould help? Thank u a lot.
Majority of Spring magic is done by BeanPostProcessors. Take a good look at them - link.
#Value wiring (and much more) is performed by AutowiredAnnotationBeanPostProcessor, you can use it for your purpose:
AutowiredAnnotationBeanPostProcessor beanPostProcessor =
appContext.getBean(AutowiredAnnotationBeanPostProcessor.class);
ServiceList srvList = new ServiceList();
beanPostProcessor.processInjection(srvList);
After that, your ServiceList should have String keystore field initialized.

Resources