Why encrypt?
Develop habits now, both the company’s projects and projects of the individual, will choose to upload source to Git server (lot, Gitee or own server), but as long as the source code to submit to the public server will be the risk of leakage source, and database configuration information as part of the source, once appear leakage source, Then all the data in the database will be made public, with unintended consequences (such as the hotel information).
So in order to avoid this kind of problem, we should at least encrypt the password of the database, so that even if we get the source code, it will not cause data leakage, but also keep the last piece of FIG leaf.
How to encrypt?
For Java projects, to quickly achieve database encryption, the simplest and feasible solution is to use Druid provided by Alibaba to achieve encryption.
What is Druid?
Druid is the best database connection pool available in alibaba’s open source Java language. Druid provides powerful monitoring and extension capabilities, including, of course, database encryption.
Druid: github.com/alibaba/dru…
What can Druid do?
- StatFilter Druid provides a very useful tool for monitoring database access performance. StatFilter is a very useful tool for monitoring database access performance online.
- Replacing DBCP and C3P0, Druid provides an efficient, powerful, and scalable database connection pool.
- If the database password is encrypted, directly write the database password in the configuration file. This is a bad behavior, which may cause security problems. DruidDruiver and DruidDataSource both support PasswordCallback.
- Druid provides a variety of logfilters that support common-logging, Log4j, and JdkLog. You can select the appropriate LogFilter to monitor your application’s database access.
- If you have programming requirements for the JDBC layer, you can easily write extensions to the JDBC layer using the Filter-chain mechanism provided by Druid.
For this article, we’ll focus on the third feature, which uses Druid to encrypt database passwords.
Encryption execution process
Before password encryption, the interaction flow of the project looked like this:
After password encryption is used, the project interaction flow looks like this:
Use Druid for encryption
This example is run in:
Spring Boot 2.4.3
MySQL 5.7
Java 1.8
The Idea of 2020.1.3
1. Add the Druid dependency
Maven project:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
Copy the code
Gradle projects:
The compile 'com. Alibaba: druid - spring - the boot - starter: 1.2.5'Copy the code
The Druid’s latest version: mvnrepository.com/artifact/co…
2. Generate ciphertext
Druid: ConfigTools (ConfigTools); Druid: ConfigTools (ConfigTools);
import com.alibaba.druid.filter.config.ConfigTools;
class MyTests {
public static void main(String[] args) throws Exception {
// The plaintext name to be encrypted
String password = "youPassword"; // [note: this is your own password]
// Call druid to generate private key, public key, and ciphertext
ConfigTools.main(newString[]{password}); }}Copy the code
The result of this code execution is as follows:
privateKey:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEApOjcMWSDzJiKVGmtcBBoQPtM9tVW2H2cnS6xZK7NrbzQXYWLQD2zefIrrx9vM vqRIHEqkmAHTuUcUXHgCxu0cwIDAQABAkAlqo5ItdWo0Jqf5zdXJlg5p2yP4HCiqCYyfKzF+2s9KEmgWZJWTctZDsgQ0iYUohORR59I+J4nabhel1x5/INpA iEA6jwSyFqMUPOh1XlrzNFek+RthOQ5n4+ALPo+vULayO0CIQC0O7JM9sIq+tg+jCGv+ypk6vbuRKY9m5W2rSRXapGm3wIgRHul3jAjIDPrF/f1HaAFL+Y0Y ws7Ebyp8/yCRWF7iA0CIALbe20q8FMcHPeI4zPWCIsHCpkmb3hEkjAOOKhGIT8DAiAqiUuz92NqKeyjmOfons1ka65EzVwA3NDhZ6+IQcnuig== publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHF Fx4AsbtHMCAwEAAQ== password:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==
As you can see from the above results, using the ConfigTools class generates three parts:
- PrivateKey: privateKey used for password encryption.
- PublicKey: publicKey used to decrypt passwords.
- Password: indicates the encrypted password.
PS: To encrypt a database, publicKey and password are used to convert plain text into ciphertext.
3. Add the configuration
After the above operations are complete, you only need to add the public key and ciphertext generated in the previous step to the project configuration file application.yml (or application.xml) to implement the encryption operation. The configuration information is as follows:
Spring: # datasource: driver-class-name: com.mysql.cj.jdbc.driver type: Com. Alibaba. Druid. Pool. DruidDataSource druid: url: JDBC: mysql: / / 127.0.0.1:3306 / testdb? serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false username: root password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ== # encrypt config filters: config connect-properties: config.decrypt: true config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMC AwEAAQ==Copy the code
Where password corresponds to the password (ciphertext) generated in the previous step, and config.decrypt.key corresponds to the publicKey (publicKey) generated in the previous step, as shown below:Here is an original configuration file for comparison with the encrypted configuration file:
4. Precautions – Lock with key
After the previous three steps, our program is ready to run, but it’s far from over!
In step 3, we wrote both the ciphertext and the public key to the configuration file. This made it possible for someone to retrieve the encrypted password using Druid when they got the ciphertext and the public key. This was like a lock with a key in it.
Therefore, the correct use posture is to find a safe place to store the public key, and dynamically set the public key to the project every time the project starts, so that the password security can be effectively guaranteed.
Correct configuration files
Next, we set the public key of Spring Boot as a configuration item, and then replace it with a specific value when the project runs. The final security configuration information is as follows:
Spring: # datasource: driver-class-name: com.mysql.cj.jdbc.driver type: Com. Alibaba. Druid. Pool. DruidDataSource druid: url: JDBC: mysql: / / 127.0.0.1:3306 / testdb? serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false username: root password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ== # encrypt config filters: config connect-properties: config.decrypt: true config.decrypt.key: ${spring.datasource.druid.publickey}Copy the code
It can be seen that the public key is modified into “${spring. The datasource. The druid. Publickey}”, this is equivalent to use placeholder FuXian give accounted for in the pit, such as project starts to change the value of concrete.
PS: “spring. The datasource. The druid. Publickey” is not fixed immutable key, the user can define the key values.
The development environment replaces the public key
The development environment only needs to configure the public key value in the startup parameter of Idea, as shown in the following figure:When we input a correct public key value, the program can run normally. When we input a wrong public key value, it will prompt decoding failure, as shown in the following figure:
Replace the public key in the production environment
The production environment only needs to dynamically set the public key value when starting the JAR package. For details, see the following command:
Java – jar XXX. The jar – spring. The datasource. The druid. Publickey = your public key
Druid works well
So when the Spring Boot project starts, Druid’s interceptor will use the ciphertext and public key to restore the password to the real password for the project to use, all without human intervention (no coding required). Druid has already wrapped it for me, so we just need to go through this configuration.
What? How does Druid restore real passwords using ciphertext and public keys?
The ConfigTools class provides the following implementation:
/ / ciphertext
String password = "VwH1mu2IUpqjfKTd+gSikiZgJTi+3Y5zFIFRfxYnH1UqHzm1K8TIHnMaV3TErBaGsVEaGV0e63pb0Ys3Wdm7Kg==";
/ / the public key
String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWIEp19IM04sB+vQXnEOH9gFNFdL5TFGSEhORgHj4MnfTfBSNaOoSgCaM8BOpjiHmwuEb7LpvmXI1x/ymUvNzE CAwEAAQ==";
// Restore to the real password
String result = ConfigTools.decrypt(publicKey, password);
System.out.println("Final result:" + result);
Copy the code
conclusion
In this article, we use Druid to encrypt the password of MySQL. Druid’s encryption process is very convenient. We don’t need to write any code, just need to add Druid dependency, and then generate ciphertext through Druid tool class. Finally, configure ciphertext into the application.yml file. At runtime, the project will convert the ciphertext into the real password through the interceptor, thus realizing the process of encrypting and decoding the MySQL password.
The last
Original is not easy, if you think this article is helpful to you, please click a like before leaving. If you can, please feel free to share it to your moments, so that more people know, thank you.
Check out the Java Chinese Community for more Druid dry products.