preface
The configuration file in the project will have a password, such as database password, mailbox password, FTP password, etc.
The configured password is exposed in clear text, which is not a safe way, especially in the production environment of large projects, because there may be many (operation and maintenance) personnel handling the configuration file, or multiple parties (Party A, Party B or even a third party). This article describes how to encrypt the password in the configuration file based on the SpringBoot project.
In this example, Jasypt, a Java encryption and decryption library, is mainly used for password encryption.
Encryption steps
1. Introduce the following dependencies into the project.
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot</artifactId> <version>1.18</version> </dependency> <dependency> <groupId>org.jasypt</groupId> <artifactId>jasypt</artifactId> <version>1.9.2</version> </dependency>
2. Add the following configuration information to the application.yml file.
# Configuration file password encryption configuration jasypt: encryptor: password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7 # Secret key algorithm: PBEWithMD5AndDES # encryption algorithm iv-generator-classname: org.jasypt.iv.NoIvGenerator
(1) From 3.0.0 jasypt spring boot At the beginning of version, the default encryption / decryption algorithm has been changed to pbewithmacsha512andaes_ 256; Versions below 3.0.0 default to PBEWithMD5AndDES;
(2) Above algorithm If it is not configured, the default secret key is the same PBEWithMD5AndDES;
(3) Above jasypt.encryptor.password Not many people understand Salt, this is the encryption key. The salt in the code is generated randomly, the length is 8 bits by default, and the generated class is by default org.jasypt.salt.RandomSaltGenerator, which can be configured through jasypt.encryptor.salt-generator-classname.
3. Obtain ciphertext through command.
java -cp /Users/shiyanfei/zlb/repository/repository-zlb/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="Mysql@1234" password=idss@2021 algorithm=PBEWithMD5AndDES
The terminal will generate ciphertext when executing the above command, where:
- /Users/shiyanfei/zlb/repository/repository-zlb/org/jasypt/jasypt/1.9.2/ yes jasypt-1.9.2.jar The path to the / lib package (under the / lib package in the Linux Environment) can be modified as required;
- input is the plaintext password, and each password needs to be executed once;
- password is the secret key.
4. Modify the original password configuration
The original plaintext password value is changed to ENC(xxx) , Where XXX is ciphertext.
For example:
1)MySQL
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/ueba?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&&useSSL=false driver-class-name: com.mysql.jdbc.Driver username: root password: ENC(2RP1Vdsa+2wdSOgu2biAJkTCU9fnkUGD)
2)Redis
spring: redis: database: 0 host: 10.20.24.48 port: 6379 password: ENC(JjPTg5GOsjV9ZBIQ2CaHr+96UgMKBgIT)
5. Add annotation
Add @ enableencrypttableproperties on the startup class.
Thinking: in the above steps, the password in the configuration file is basically encrypted according to the usage of Jasypt. However, please think about whether this treatment is really safe and reasonable?
optimization
If we follow strict requirements, this treatment is not perfect. Because the secret key and ciphertext are exposed, it is still unsafe. So, how to deal with it? The following is one of my ideas, which has been practiced in the project.
1. First, the secret key is generated through another gadget, which is independent of the project;
The gadget is an independent and complete program with packaging script and start stop script. Due to space constraints, the source code has been uploaded to GitHub.
2. Secondly, the secret key is not exposed in the configuration file, but written into the code (under normal circumstances, the secret key will not change);
/************************ CHANGE REPORT HISTORY ******************************\ ** Product VERSION,UPDATED BY,UPDATE DATE * * DESCRIPTION OF CHANGE: modify(M),add(+),del(-) * *-----------------------------------------------------------------------------* * V3.0.12,shiyanfei,2021-09-14 * create * *************************** END OF CHANGE REPORT HISTORY ********************/ package com.idss.radar.common.ums.bean; import org.jasypt.encryption.StringEncryptor; import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author : shiyanfei * @description : <p>Automatically configure encrypted information</p> * @see : com.idss.radar.common.ums.bean * @since : 2021-09-14 */ @Configuration public class EncryptorConfig { @Bean("jasyptStringEncryptor") public StringEncryptor jasyptStringEncryptor() { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); SimpleStringPBEConfig config = new SimpleStringPBEConfig(); config.setPassword("EbfYkitulv73I2p0mXI50JMXoaxZTKJ7"); // The notes section is the default configuration config.setAlgorithm("PBEWithMD5AndDES"); // config.setKeyObtentionIterations("1000"); config.setPoolSize("1"); // config.setProviderName("SunJCE"); // config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator"); // config.setStringOutputType("base64"); encryptor.setConfig(config); return encryptor; } }
3. Delete information from profile
# Configuration file password encryption configuration jasypt: encryptor: password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7 # Secret key algorithm: PBEWithMD5AndDES # encryption algorithm iv-generator-classname: org.jasypt.iv.NoIvGenerator
4. Another advantage of the above processing is that the optimized project supports both plaintext and ciphertext. Ciphertext only needs to add functions ENC(xxxx).
summary
There is no best solution to the problem, only better. With the continuous improvement of requirements and in-depth thinking, the solution to the problem will gradually approach perfection.