zoukankan      html  css  js  c++  java
  • SpringBoot项目配置文件中密码的加密

    作者:追梦1819
    原文:https://www.cnblogs.com/yanfei1819/p/15565862.html
    版权声明:本文为博主原创文章,转载请附上博文链接!
    公众号:追梦1819


    前言

    项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。

    配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文件经手的(运维)人员可能很多,也可能是多方的(甲方、乙方甚至第三方)。本文讲述基于 SpringBoot 项目对配置文件中的密码进行加密。

    本文实例中密码加密主要用到的是 Jasypt,一个Java的加解密库。


    加密步骤

    1、在项目中引入以下依赖。

            <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、在application.yml文件中添加以下配置信息。

    # 配置文件密码加密配置
    jasypt:
      encryptor:
        password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7 # 秘钥
        algorithm: PBEWithMD5AndDES # 加密算法
        iv-generator-classname: org.jasypt.iv.NoIvGenerator
    

    (1)从3.0.0jasypt-spring-boot 版本开始,默认的加密/解密算法已更改为PBEWITHHMACSHA512ANDAES_256;3.0.0以下版本默认为 PBEWithMD5AndDES;

    (2)上述algorithm 不配置的话,其默认的秘钥也是 PBEWithMD5AndDES

    (3)以上的 jasypt.encryptor.password 并不是很多人理解的 salt(盐),这是加密密钥。代码中的salt是随机生成的,长度默认为8位,生成类默认是 org.jasypt.salt.RandomSaltGenerator,可以通过配置 jasypt.encryptor.salt-generator-classname来修改。

    3、通过命令获取密文。

    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
    

    终端执行上述命令会生成密文,其中:

    • /Users/shiyanfei/zlb/repository/repository-zlb/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar 的路径(Linux环境中应该是在/lib包下面),根据需求修改;
    • input 是明文密码,每一个密码都需要执行一次;
    • password 是秘钥。

    4、修改原来的密码配置

    原来的明文密码值,改为 ENC(xxx) ,其中xxx是密文。

    例如:

    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、添加注解

    启动类上添加@EnableEncryptableProperties

    思考:以上的步骤中,根据 Jasypt 的用法,基本上完成了对配置文件中密码的加密。但是,请思考一下,这样处理是否真的安全合理?


    优化

    如果按照严格的要求来,这样处理并不是完善的。因为秘钥和密文都暴露出来,依然是不安全的。那么,要如何处理呢?以下是我其中的一个思路,并已在项目中实践。

    1、首先,秘钥通过另一个小工具生成,该小工具与项目无关;

    小工具是一个独立的完整程序,有打包脚本和启停脚本。篇幅所限,已将源码上传至 GitHub

    2、其次,秘钥不暴露在配置文件中,而写入代码中(正常情况下,秘钥基本不会变动);

    /************************ 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>自动配置加密信息</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");
          	// 注释部分为配置默认
            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、删除配置文件中的信息

    # 配置文件密码加密配置
    jasypt:
      encryptor:
        password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7 # 秘钥
        algorithm: PBEWithMD5AndDES # 加密算法
        iv-generator-classname: org.jasypt.iv.NoIvGenerator
    

    4、以上处理还有一个好处,就是优化后的项目,既支持明文,也支持密文,密文只要加函数 ENC(xxxx)


    总结

    解决问题的方案没有最好的,只有更好的。随着要求的不断提高,思考的不断深入,解决问题的方案才会逐步趋近完美。



    本文来自博客园,作者:追梦1819,转载请注明原文链接:https://www.cnblogs.com/yanfei1819/p/15565862.html

  • 相关阅读:
    Django连接SQL Server,安装相关扩展包及相关配置
    安装pipenv
    报错及网络上的解决方案
    Nucleus-SE迁移:未实现的设施和兼容性
    RTOS诊断和错误检查
    Nucleus SE RTOS初始化和启动
    Nucleus 实时操作系统中断(下)
    Nucleus 实时操作系统中断(上)
    系统时间
    应用程序计时器
  • 原文地址:https://www.cnblogs.com/yanfei1819/p/15565862.html
Copyright © 2011-2022 走看看