How to define the encryption of passwords in SpringBoot project configuration files

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.

Tags: Python Java Programming Programmer architecture

Posted on Wed, 17 Nov 2021 01:02:18 -0500 by foreverdita