当前位置: 首页 > article >正文

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

一、前言

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

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

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

二、解决方法

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

        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>

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;
    }

http://www.kler.cn/news/9823.html

相关文章:

  • ChatGPT 指令大全
  • 力扣119杨辉三角 II:代码实现 + 方法总结(数学规律法 记忆法/备忘录)
  • 低静态电流-汽车电池反向保护系统的方法
  • 第八章 Vite4+Vue3+Vtkjs 完整demo演示
  • 刘二大人《Pytorch深度学习实践》第十一讲卷积神经网络(高级篇)
  • 工厂模式白话 - 3种都有哦
  • C语言——变参函数
  • 为什么Java8不使用CMS作为默认垃圾收集器
  • 死锁的检测和案例
  • Qt使用std::thread更新QPlainTextEdit内容
  • 透过Gartner最新报告,认识“超级边缘”
  • Java 包详细讲解
  • ChatGPT想干掉开发人员,做梦去吧
  • ERTEC200P-2 PROFINET设备完全开发手册(4-2)
  • 4.9--计算机网络之TCP篇之TCP 重传、滑动窗口、流量控制、拥塞控制--(复习+大总结)---好好沉淀,沉下心来
  • 真题详解(Flynn分类)-软件设计(四十六)
  • 【Linux】线程概念详析
  • 博客平台用户模块设计原则:构建简洁、高效的用户体验
  • 100种思维模型之非共识思维模型-48
  • 板块模型构建、k点选定及Miller指数对表面分类
  • 代码随想录算法训练营第五十二天 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组
  • 液压传动与控制实验教学培训系统平台
  • Bootloader的作用
  • [ 应急响应基础篇 ] Windows系统隐藏账户详解(Windows留后门账号)
  • 从存算分离说起:金融行业数据库分布式改造之路
  • 【Linux】工具(5)——gdb
  • 浏览器:好用的浏览器插件,亲测好用
  • 分布式场景下,Apache YARN、Google Kubernetes 如何解决资源管理问题?
  • Quaternion插值方法
  • FFMPEG VCL Pack Crack显示位置支持或光标