springboot项目配置文件不允许出现明文密码的解决方法(jasypt使用方法)

一、前言

出于安全考虑,java项目配置文件中不允许出现明文密码;

为了解决这个问题,可以使用jasypt这个jar包,这个jar包可以对字符串进行加解密,项目中引入后,在配置文件中写加密后的密码即可,项目启动时这个jar包就会对密码进行解密,不影响项目正常使用。

java类中也不允许出现明文密码,也可以利用这个jar包进行加解密。

二、解决方法

1.springboot项目中,在pom.xml里引入:

        
            com.github.ulisesbocchio
            jasypt-spring-boot-starter
            2.1.2
        

2.在启动类Application.java中,引入:

import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;

@EnableEncryptableProperties

3.可以编写一个ENC_Util.java工具类,用来对字符串加解密(获取加密字符串、解密java类中的密码可以用,解密配置文件里的密码用不到),内容如下:


import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;


public class ENC_Util {

    private static final String SALT = "mysalt";

    /**
     * jasypt-1.9.3 加解密工具类( jasypt-spring-boot-starter 是 2.1.2 )
     */

        private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
        private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";

    public static String encryptWithMD5(String plainText) {
        return encryptWithMD5(plainText,SALT);
    }

    public static String decryptWithMD5(String plainText) {
        //java项目里用的解密方法,解密时,需要把ENC()去掉才行
        if(plainText == null || plainText.length()<=5){
            return "";
        }else{
            //截取字符串,把ENC()去掉
            plainText = plainText.substring(4,plainText.length()-1);
        }
        return decryptWithMD5(plainText,SALT);
    }

        /**
         * Jasyp2.x 加密(PBEWithMD5AndDES)
         * @param		 plainText      待加密的原文
         * @param		 factor         加密秘钥
         * @return       java.lang.String
         */
        public static String encryptWithMD5(String plainText, String factor) {
            // 1. 创建加解密工具实例
            StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            // 2. 加解密配置
            EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
            config.setAlgorithm(PBEWITHMD5ANDDES);
            config.setPassword(factor);
            encryptor.setConfig(config);
            // 3. 加密
            return encryptor.encrypt(plainText);
        }

        /**
         * Jaspy2.x 解密(PBEWithMD5AndDES)
         * @param		 encryptedText      待解密密文
         * @param		 factor             解密秘钥
         * @return       java.lang.String
         */
        public static String decryptWithMD5(String encryptedText, String factor) {
            // 1. 创建加解密工具实例
            StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            // 2. 加解密配置
            EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
            config.setAlgorithm(PBEWITHMD5ANDDES);
            config.setPassword(factor);
            encryptor.setConfig(config);
            // 3. 解密
            return encryptor.decrypt(encryptedText);
        }

        /**
         * Jasyp3.x 加密(PBEWITHHMACSHA512ANDAES_256)
         * @param		 plainText  待加密的原文
         * @param		 factor     加密秘钥
         * @return       java.lang.String
         */
        public static String encryptWithSHA512(String plainText, String factor) {
            // 1. 创建加解密工具实例
            PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
            // 2. 加解密配置
            SimpleStringPBEConfig config = new SimpleStringPBEConfig();
            config.setPassword(factor);
            config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
            // 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
            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);
            // 3. 加密
            return encryptor.encrypt(plainText);
        }

        /**
         * Jaspy3.x 解密(PBEWITHHMACSHA512ANDAES_256)
         * @param		 encryptedText  待解密密文
         * @param		 factor         解密秘钥
         * @return       java.lang.String
         */
        public static String decryptWithSHA512(String encryptedText, String factor) {
            // 1. 创建加解密工具实例
            PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
            // 2. 加解密配置
            SimpleStringPBEConfig config = new SimpleStringPBEConfig();
            config.setPassword(factor);
            config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
            // 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
            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);
            // 3. 解密
            return encryptor.decrypt(encryptedText);
        }

        public static void main(String[] args) {
            //待加密字符串
            String plainText = "123456";
            //这个每次跑的结果不一样
            String encryptWithMD5Str = encryptWithMD5(plainText, SALT);
            //虽然不一样,这个也能正常执行
            String decryptWithMD5Str = decryptWithMD5(encryptWithMD5Str, SALT);

            System.out.println("加密前:"+plainText);
            System.out.println("加密后:"+encryptWithMD5Str);
            System.out.println("解密后:"+decryptWithMD5Str);

            //String encryptWithSHA512Str = encryptWithSHA512(plainText, factor);
            //String decryptWithSHA512Str = decryptWithSHA512(encryptWithSHA512Str, factor);

            //System.out.println("采用SHA512加密前原文密文:" + encryptWithSHA512Str);
            //System.out.println("采用SHA512解密后密文原文:" + decryptWithSHA512Str);
        }

}

4.举个例子,上面的密码是123456,盐值是mysalt,加密后的结果是dLJEFB7/7QJYan40UefGvQ==
这个每次加密后的结果都不一样,不过解密后的结果是一样的,都是123456

5.修改配置文件application.yml,先加上jasypt的配置信息:

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    pool-size: 1
    salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
    password: mysalt

注意,这里的password就是盐值,如果这里安全人员也不允许写,那就可以写在启动命令中,例如:

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    pool-size: 1
    salt-generator-classname: org.jasypt.salt.RandomSaltGenerator

然后项目启动命令里加上:

java -jar -Djasypt.encryptor.password=mysalt

6.修改配置文件application.yml,在之前明文密码的地方,用ENC(密文密码)代替,例如:

spring.datasource:
  url: jdbc:mysql://10.123.123.123:3306/mydbname?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  username: root
  password: ENC(dLJEFB7/7QJYan40UefGvQ==)
  driver-class-name: com.mysql.cj.jdbc.Driver

这个在项目启动后,jar包就会把dLJEFB7/7QJYan40UefGvQ==解密成123456,并正确连接数据库了。

7.如果java文件中还有明文密码,也可以换成密文密码,然后用上方的ENC_Util.java解密一下,例如:

    private static Connection getConnection() {
        Connection conn = null;
        try {
        
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://10.123.123.123:3306/mydbname?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
            String username = "root";
            
            //这里是util里截取字符串后才解密的,也可以不加ENC(),然后util里也不截取字符串
            String password = ENC_Util.decryptWithMD5("ENC(dLJEFB7/7QJYan40UefGvQ==)");
            //String password = ENC_Util.decryptWithMD5("dLJEFB7/7QJYan40UefGvQ==");
            
            Properties props = new Properties();
            props.setProperty("user", username);
            props.setProperty("password", password);
            conn = DriverManager.getConnection(url, props);
            
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return conn;
    }

你可能感兴趣的:(java,spring,boot,spring)