First look at a typical configuration file
... Omitted...## Configure MySQL database connection spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://121.196.xxx.xxx:3306/user?useUnicode=true&characterEncoding=utf-8spring.datasource.username=rootspring.datasource.password=123456## Configure Redis cache connection Redish.host=121.196.xxx.xxxredis.port=6379redis.password=111111## Configure sms SMS service connection ali.sms.access_key_id=2zHmLdxAes7Bbe2wali.sms.access_key_secret=bImWdv6iy0him8ly... Omit ...
This is an excerpt from the application.properties configuration file of a typical Spring Boot project.
Shh... Tell me secretly, do many friends write this way?
”
This seems to be fine at first glance, and many people will take it for granted. Including I have seen many projects (including many open source projects) written like this.
But after careful consideration, I found:
Yes! Many project configuration files, including database passwords, cache passwords, or keys for some third-party services, are directly included, and no encryption is done!
Some people would say that this configuration file is my own anyway, what are the risks?
, I saw an example before, a programmer uploaded his company's project code to his own GitHub repository, but the configuration file forgot to process it, resulting in the company's database leak. The key problem is that this company is still a hotel management company, so the consequences can be imagined...
From another perspective, if all the important information in the project configuration file at that time were encrypted, then this scene would probably not have happened. Therefore, even the project configuration file, important information must be encrypted! What information should be added to
What about password?
Generally speaking, in the project configuration file, all configuration items (or fields) involving information security should be processed. Typical examples are: databases used in
- , cached passwords used in
- , middleware used in
- , message queue passwords used in
- , various third-party services, access_Key
- , other third-party services communication letters Interesting
- ... etc.
In short, the key fields should be protected, at least they cannot be written directly in the configuration file in plain text! How to encrypt configuration items in
?
method is very simple, and it can be completed in a few steps. Let's first demonstrate a simplest version:
1. First, build a basic Spring Boot project
This will not be repeated.
2. Introducing jasypt-spring-boot encryption component
. Through jasypt-spring-boot, this out-of-the-box encryption component, introduces Jasypt, a powerful encryption library.
dependencygroupIdcom.github.ulisesbocchio/groupIdartifactIdjasypt-spring-boot-starter/artifactIdversion3.0.2/version/dependency
3. Configure the encryption key
in Spring The following configuration has been added to the Boot project configuration file application.properties:
jasypt.encryptor.password=CodeSheep
It can be understood that jasypt will use this custom encryption key to encrypt important items in the configuration file.
First look at a typical configuration file
... Omitted...## Configure MySQL database connection spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://121.196.xxx.xxx:3306/user?useUnicode=true&characterEncoding=utf-8spring.datasource.username=rootspring.datasource.password=123456## Configure Redis cache connection Redish.host=121.196.xxx.xxxredis.port=6379redis.password=111111## Configure sms SMS service connection ali.sms.access_key_id=2zHmLdxAes7Bbe2wali.sms.access_key_secret=bImWdv6iy0him8ly... Omit ...
This is an excerpt from the application.properties configuration file of a typical Spring Boot project.
Shh... Tell me secretly, do many friends write this way?
”
This seems to be fine at first glance, and many people will take it for granted. Including I have seen many projects (including many open source projects) written like this.
But after careful consideration, I found:
Yes! Many project configuration files, including database passwords, cache passwords, or keys for some third-party services, are directly included, and no encryption is done!
Some people would say that this configuration file is my own anyway, what are the risks?
, I saw an example before, a programmer uploaded his company's project code to his own GitHub repository, but the configuration file forgot to process it, resulting in the company's database leak. The key problem is that this company is still a hotel management company, so the consequences can be imagined...
From another perspective, if all the important information in the project configuration file at that time were encrypted, then this scene would probably not have happened. Therefore, even the project configuration file, important information must be encrypted! What information should be added to
What about password?
Generally speaking, in the project configuration file, all configuration items (or fields) involving information security should be processed. Typical examples are: databases used in
- , cached passwords used in
- , middleware used in
- , message queue passwords used in
- , various third-party services, access_Key
- , other third-party services communication letters Interesting
- ... etc.
In short, the key fields should be protected, at least they cannot be written directly in the configuration file in plain text! How to encrypt configuration items in
?
method is very simple, and it can be completed in a few steps. Let's first demonstrate a simplest version:
1. First, build a basic Spring Boot project
This will not be repeated.
2. Introducing jasypt-spring-boot encryption component
. Through jasypt-spring-boot, this out-of-the-box encryption component, introduces Jasypt, a powerful encryption library.
dependencygroupIdcom.github.ulisesbocchio/groupIdartifactIdjasypt-spring-boot-starter/artifactIdversion3.0.2/version/dependency
3. Configure the encryption key
in Spring The following configuration has been added to the Boot project configuration file application.properties:
jasypt.encryptor.password=CodeSheep
It can be understood that jasypt will use this custom encryption key to encrypt important items in the configuration file.
4, encryption test
For the sake of easy testing, we directly extend Spring Boot project startup class, execute encryption test code when the project starts, look at the effect directly
@SpringBootApplicationpublicclassSpringBootconfigml9EncryptApplicationimplementsCommandLineRunner{@AutowiredprivateApplicationContexttml9appCtx;@AutowiredprivateStringEncryptorcodeSheepEncrypto rBean;publicstaticvoidmain(String[]args){SpringApplication.run(SpringBootConfigEncryptApplication.class,args);}@Overridepublicvoidrun(String...args)throwsException{Environmentenvironment=appCtx.getBean(Environment.class);//First get the original plaintext information in the configuration file Str ingmysqlOriginPswd=environment.getProperty("spring.datasource.password");StringredisOriginPswd=environment.getProperty("redis.password");StringaliSmsOriginAk=environment.getProperty("ali.sms.access_key_secret");//EncryptedStringmysqlEncryptedPswd=encrypt(mysqlOriginPswd);Stringr eisEncryptedPswd=encrypt(redisOriginPswd);StringaliSmsEncryptedAk=encrypt(aliSmsOriginAk);//Compare the results before and after printing the encryption System.out.println("MySQL original plaintext password is: "+mysqlOriginPswd);System.out.println("Redis original plaintext password is: "+redisOriginPswd);System.out.println("Aliyun SMS original AccessKey password is: "+aliSmsOriginAk);Syste m.out.println("====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== originPassord){StringencryptStr=codeSheepEncryptorBean.encrypt(originPassord);returnencryptStr;}privateStringdecrypt(StringencryptedPassword){StringdecryptStr=codeSheepEncryptorBean.decrypt(encryptedPassword);returndecryptStr;}}
Run the project, console print:
M ySQL original plaintext password is: 123456Redis original plaintext password is: 111111 Alibaba Cloud SMS original AccessKey password is: bImWdv13da894mly=========================================================================== The result after encryption of MySQL original plaintext password is: IV7SyeQ OfG4GhiXeGLboVgOLPDO+dJMDoOdmEOQp3KyVjruI+dKKeehsTriWPKboRedis The result after encryption of the original plaintext password is: litUkxJ3fN6+//Emq3vZ+y4o7ZOnZ8doOy7NrgJIDLoNWGG0m3ygGeQh/dEr oKvv Alibaba Cloud SMS original AccessKey password encryption result is: MAhrOs20DY0RU/c1IKyLCt6dWZqLLOO4wUcK9GBgSxNII3C+y+SRptors+FyNz55xNDslhDnpWllhcYPwZsO5A==
5. Modify the configuration file and replace the configuration item to be encrypted
We get the encryption result obtained in the previous step and replace the original plaintext password in the configuration file with the corresponding result of the previous step, just like this:
So it is recommended that all important information in the configuration file be handled in this way!
6, view password decryption results
@SpringBootApplicationpublicclassSpringBootConfigEncryptApplication implementationsCommandLineRunner{@AutowiredprivateApplicationContextappCtx;@AutowiredprivateStringEncryptorcodeSheepEncryptorBean;publicstaticvoidmain(Str ing[]args){SpringApplication.run(SpringBootConfigEncryptApplication.class,args);}@Overridepublicvoidrun(String...args)throwsException{Environmentenvironment=appCtx.getBean(Environment.class);//First get the configuration item in the configuration file StringmysqlOriginPswd=environment.getProperty("spring.dat asource.password");StringredisOriginPswd=environment.getProperty("redis.password");StringaliSmsOriginAk=environment.getProperty("ali.sms.access_key_secret");//Print the decrypted result System.out.println("MySQL original plaintext password is: "+mysqlOriginPswd);System.out.println("Redis original plaintext password is: "+redisOrig inPswd);System.out.println("Aliyun SMS original AccessKey password is: "+aliSmsOriginAk);}}
Print result:
MySQL original plaintext password is: 123456Redis original plaintext password is: 111111Aliyun SMS original AccessKey password is: bImWdv13da894mly
It is obvious that when used in the code, the jasypt-spring-boot component will automatically decrypt the configuration item encryption field wrapped in the ENC() syntax, and the data can be restored.
kids, do you have many question marks?
At this time, I think many friends are puzzled. Typical examples are:
1. The encryption key must be placed in ENC()? Why ENC?
2. Although the original configuration item involving information security is encrypted, the custom encryption key jasypt.encryptor.password=CodeSheep If it is leaked, isn't there any chance that others can decrypt it?
Continue to these problems.
Custom encryption pre-suffix
If you are unwilling to use the ENC provided by jasypt to mark the encrypted field, you can completely change it to a custom pre-suffix tag. For example, I want to change to CodeSheep() to mark the encrypted field. At this time, you only need to configure the pre-suffix in the configuration file:
jasypt.encryptor.property.prefix=C odeSheep(jasypt.encryptor.property.suffix=)
At this time, the encryption field can be placed in the field marked by CodeSheep():
makes encryption more secure
Although after the above encryption, configuration items involving information security will definitely become safer, there is no doubt about this!
But if the custom encryption key jasypt.encryptor.password=CodeSheep in the configuration file is leaked, then our encryption field may still be decrypted by others. For this reason, there are several tasks that can make encryption more secure.
1. When using custom encrypter
, the above experiment was used to encrypt the encryption rule , which may make it insecure when the custom encryption key leaks. For this we can customize encryption rules.
custom encryption rules are very simple. You only need to provide custom encryptor configuration class , for example, I can customize a custom encryption here called codeSheepEncryptorBean type encryptor:
@ConfigurationpublicclassCodeSheepEncryptorCfg{@Bean(name="codeSheepEncryptorBean")publicStringEncryptorcodesheetStringEncryptor(){PooledPBEStringEncryptoren cryptor=newPooledPBEStringEncryptor();SimpleStringPBEConfigconfig=newSimpleStringPBEConfig();config.setPassword("CodeSheep");config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");config.setKeyObtentionIte odds("1000");config.setPoolSize("1");config.setProviderName("SunJCE");config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGe nerator");config.setStringOutputType("base64");encryptor.setConfig(config);returnencryptor;}}
Note that Here the name of the bean needs to be explicitly specified (the default name is jasyptStringEncryptor). If you use a custom name like this, you also need to use Spring Boot's application.properties configuration file specifies the name of the bean, just like this:
jasypt.encryptor.bean=codeSheepEncryptorBean
2. Do not write the encryption key in the configuration file
. If you think the above If this method may lead to the leakage of the encryption key (after all, it is still written in the configuration file), then we can simply remove the encryption key from the configuration file and replace it with . Three methods: :
- . Method 1 : Directly as the command line parameter at the start of the program, bringing
java -jar yourproject.jar --jasypt.encryptor.password=CodeSheep
- Mode 2 : directly as when the program starts, apply environment variable to bring
java -Djasypt.encryptor.password=CodeSheep -jar yourproject.jar
- way three : It can even be used as the system environment variable to bring in
For example, we set the system environment variable JASYPT_ENCRYPTOR_PASSWORD = CodeSheep, and then directly configure the following configuration in the Spring Boot project configuration file:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
will also be much safer at this time.
号...
OK, I said so much, if the important information in your project configuration file is not encrypted, promise me, don’t say anything, hurry up and change it all secretly, hurry up! speed! Run and move forward!
kids, do you have many question marks?
At this time, I think many friends are puzzled. Typical examples are:
1. The encryption key must be placed in ENC()? Why ENC?
2. Although the original configuration item involving information security is encrypted, the custom encryption key jasypt.encryptor.password=CodeSheep If it is leaked, isn't there any chance that others can decrypt it?
Continue to these problems.
Custom encryption pre-suffix
If you are unwilling to use the ENC provided by jasypt to mark the encrypted field, you can completely change it to a custom pre-suffix tag. For example, I want to change to CodeSheep() to mark the encrypted field. At this time, you only need to configure the pre-suffix in the configuration file:
jasypt.encryptor.property.prefix=C odeSheep(jasypt.encryptor.property.suffix=)
At this time, the encryption field can be placed in the field marked by CodeSheep():
makes encryption more secure
Although after the above encryption, configuration items involving information security will definitely become safer, there is no doubt about this!
But if the custom encryption key jasypt.encryptor.password=CodeSheep in the configuration file is leaked, then our encryption field may still be decrypted by others. For this reason, there are several tasks that can make encryption more secure.
1. When using custom encrypter
, the above experiment was used to encrypt the encryption rule , which may make it insecure when the custom encryption key leaks. For this we can customize encryption rules.
custom encryption rules are very simple. You only need to provide custom encryptor configuration class , for example, I can customize a custom encryption here called codeSheepEncryptorBean type encryptor:
@ConfigurationpublicclassCodeSheepEncryptorCfg{@Bean(name="codeSheepEncryptorBean")publicStringEncryptorcodesheetStringEncryptor(){PooledPBEStringEncryptoren cryptor=newPooledPBEStringEncryptor();SimpleStringPBEConfigconfig=newSimpleStringPBEConfig();config.setPassword("CodeSheep");config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");config.setKeyObtentionIte odds("1000");config.setPoolSize("1");config.setProviderName("SunJCE");config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGe nerator");config.setStringOutputType("base64");encryptor.setConfig(config);returnencryptor;}}
Note that Here the name of the bean needs to be explicitly specified (the default name is jasyptStringEncryptor). If you use a custom name like this, you also need to use Spring Boot's application.properties configuration file specifies the name of the bean, just like this:
jasypt.encryptor.bean=codeSheepEncryptorBean
2. Do not write the encryption key in the configuration file
. If you think the above If this method may lead to the leakage of the encryption key (after all, it is still written in the configuration file), then we can simply remove the encryption key from the configuration file and replace it with . Three methods: :
- . Method 1 : Directly as the command line parameter at the start of the program, bringing
java -jar yourproject.jar --jasypt.encryptor.password=CodeSheep
- Mode 2 : directly as when the program starts, apply environment variable to bring
java -Djasypt.encryptor.password=CodeSheep -jar yourproject.jar
- way three : It can even be used as the system environment variable to bring in
For example, we set the system environment variable JASYPT_ENCRYPTOR_PASSWORD = CodeSheep, and then directly configure the following configuration in the Spring Boot project configuration file:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
will also be much safer at this time.
号...
OK, I said so much, if the important information in your project configuration file is not encrypted, promise me, don’t say anything, hurry up and change it all secretly, hurry up! speed! Run and move forward!