目录

方式一:手动配置加密处理(手动配置分三种情况)

方式二:spring boot整合Jasypt实现yml配置文件敏感信息加密


yml配置文件敏感信息无非就是数据库密码,redis密码,以及整合的其他实例的密码。
     
本文有手动配置加密处理整合Jasypt方式两种方式
      注意:整合Jasypt有个大坑:Spring boot2.2.x版本无论搭配Jasypt任何版本,打包后在Windows上正常运行,但是发布到linux上运行都会出现无法解密的问题!


方式一:手动配置加密处理(手动配置分三种情况)


1、数据库密码加密
     如果项目整合的mybatis-plus存在数据源自动配置,需要通过yml获取DataSource,并在
MybatisPlusConfig的java类配置中创建SqlSessionFactory,具体方式如下:

yml配置:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:kingbase8://localhost:54321/dg_ins_test
    username: SYSTEM
    password: ED5wLgc3Mnw=
    #是否加密
    decrypt: true
    driver-class-name: com.kingbase8.Driver
DateSourceConfig类:
@Configuration
public class DateSourceConfig {

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.decrypt}")
    private boolean decrypt;


    @Bean(name = "dataSource")
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setDriverClassName(driverClassName);
        datasource.setUrl(url);
        datasource.setUsername(username);
        if (decrypt) {
            datasource.setPassword(SM4Util.decryptStr(password));
        } else {
            datasource.setPassword(password);
        }
        return datasource;
    }

}
MybatisPlusConfig类:
@Bean(name = "masterSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    //全局配置
    GlobalConfig globalConfig = new GlobalConfig();
    globalConfig.setMetaObjectHandler(new MybatisMateHandler());
    MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
    MybatisConfiguration conf = new MybatisConfiguration();
    //驼峰命名
    conf.setMapUnderscoreToCamelCase(true);
    //mybatis二级缓存
    conf.setCacheEnabled(false);
    //打印执行的sql,开发时候用
    conf.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
    //配置JdbcTypeForNull, oracle数据库必须配置
    conf.setJdbcTypeForNull(null);
    //MyBatis 自动映射时未知列或未知属性处理策略 NONE:不做任何处理 (默认值), WARNING:以日志的形式打印相关警告信息, FAILING:当作映射失败处理,并抛出异常和详细信息
    conf.setAutoMappingUnknownColumnBehavior(WARNING);
    sessionFactoryBean.setConfiguration(conf);
    //分页插件配置
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/**/*.xml"));
    sessionFactoryBean.setPlugins(interceptor);

    sessionFactoryBean.setDataSource(dataSource);
    sessionFactoryBean.setGlobalConfig(globalConfig);
    sessionFactoryBean.setTypeAliasesPackage("com.crcm.model.entity");

    return sessionFactoryBean.getObject();
}

2、redis密码加密
      此处采用AOP方式处理加密过的redis密码

yml配置:

spring:
  redis:
    #Redis索引0~15,默认为0
    database: 1
    host: 10.222.252.33
    port: 6379
    #密码
    password: LN7kk55braw=
    #是否加密
    decrypt: true


      新增一个切点类:
     

@Component
public class RedisPointCut {

    @Pointcut("execution(* org.springframework.boot.autoconfigure.data.redis.RedisProperties.getPassword())")
    public void getRedisConnectionPwd(){
    }
}

RedisConfig配置类中加入如下代码:

@Configuration
@Aspect
@EnableCaching //启用缓存
public class RedisConfig extends CachingConfigurerSupport {

    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.decrypt}")
    private boolean decrypt;

    @Autowired
    private RedisProperties redisProperties;

    @Before("com.crcm.base.config.redis.RedisPointCut.getRedisConnectionPwd()")
    public void setRedisProperties(){
        if(!ObjectUtils.isEmpty(password)){
            if(decrypt){
                redisProperties.setPassword(SM4Util.decryptStr(password));
            }else{
                redisProperties.setPassword(password);
            }
        }
    }
    
}

3、普通实例配置加密处理:
     比如:minio文件系统配置(普通配置config配置类中可以直接获取到密码,所以操作简单)
     yml配置:

#文件存储配置
file:
  #当前激活的文件服务
  active:
    minio
  minio:
    #服务器地址
    url: https://456.1222.com
    #用户名
    access-key: ak
    #密码
    secret-key: AEM5TvR4MeX4PwZJgl2YWQ==
    #根目录
    bucket-name: lty
    chunk-bucKet: test
    #分享链接过期时间 7天
    file-expire-second: 604800
    #是否加密
    decrypt: true
MinioProperties类如下:

/**
 * minio 配置信息
 *
 */
@Configuration
@ConfigurationProperties(prefix = "file.minio")
public class MinioProperties {
   /**
    * minio 服务地址 http://ip
    */
   private String url;
   /**
    * 端口
    */
   private Integer port;

   /**
    * 用户名
    */
   private String accessKey;

   /**
    * 密码
    */
   private String secretKey;
   /**
    * 是否加密
    */
   private boolean decrypt;
   /**
    * 根目录名称
    */
   private String bucketName;
   /**
    * 存储分块上传文件的桶
    */
   private String chunkBucKet;
   /**
    * 分享链接过期时间(秒)
    */
   private Integer fileExpireSecond;

   public String getUrl() {
      return url;
   }

   public void setUrl(String url) {
      this.url = url;
   }

   public Integer getPort() {
      return port;
   }

   public void setPort(Integer port) {
      this.port = port;
   }

   public String getAccessKey() {
      return accessKey;
   }

   public void setAccessKey(String accessKey) {
      this.accessKey = accessKey;
   }

   public String getSecretKey() {
      return secretKey;
   }

   public void setSecretKey(String secretKey) {
      if(this.decrypt){
         this.secretKey = SM4Util.decryptStr(secretKey);
      }else{
         this.secretKey = secretKey;
      }
   }

   public boolean isDecrypt() {
      return decrypt;
   }

   public void setDecrypt(boolean decrypt) {
      this.decrypt = decrypt;
   }

   public String getBucketName() {
      return bucketName;
   }

   public void setBucketName(String bucketName) {
      this.bucketName = bucketName;
   }

   public String getChunkBucKet() {
      return chunkBucKet;
   }

   public void setChunkBucKet(String chunkBucKet) {
      this.chunkBucKet = chunkBucKet;
   }

   public Integer getFileExpireSecond() {
      return fileExpireSecond;
   }

   public void setFileExpireSecond(Integer fileExpireSecond) {
      this.fileExpireSecond = fileExpireSecond;
   }
}
SM4Util加密工具如下:
public class SM4Util {
    private final static String key="589645845521";
    //加密方法
    public static String encryptBase64(String data){
        SymmetricCrypto sm4 =new SymmetricCrypto(SymmetricAlgorithm.DES,key.getBytes(StandardCharsets.UTF_8));
        return  sm4.encryptBase64(data);
    }
    //解密方法
    public static String decryptStr(String data){
        SymmetricCrypto sm4 =new SymmetricCrypto(SymmetricAlgorithm.DES,key.getBytes(StandardCharsets.UTF_8));
        return sm4.decryptStr(data);
    }

    public static void main(String[] args) {
//        System.out.println(decryptStr("LN7kk55braw="));
        System.out.println(encryptBase64("123"));
    }
}
以上就是手动配置加密的三种处理方式。

方式二:spring boot整合Jasypt实现yml配置文件敏感信息加密


    整合前请详细浏览Jasypt地址:https://github.com/ulisesbocchio/jasypt-spring-boot


 注意每个Jasypt版本对应的spring boot版本,spring boot2.2.x版本整合可能会有bug
 

1、导入依赖
本项目的spring boot版本为2.1.4.RELEASE  Jasypt版本为2.1.0

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>
2、新增密码加密解密工具类
@SpringBootTest
@RunWith(SpringRunner.class)
public class JasyptTestUtil {

    @Test
    public void testEncrypt() throws Exception {
        StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

        config.setAlgorithm("PBEWithMD5AndDES");          // 加密的算法,这个算法是默认的
        config.setPassword("secrect");                        // 加密的密钥,随便自己填写,很重要千万不要告诉别人
        standardPBEStringEncryptor.setConfig(config);
        String plainText = "123456";         //自己的密码
        String encryptedText = standardPBEStringEncryptor.encrypt(plainText);
        System.out.println("密码:" + encryptedText);
    }

    @Test
    public void testDe() throws Exception {
        StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

        config.setAlgorithm("PBEWithMD5AndDES");
        config.setPassword("secrect");
        standardPBEStringEncryptor.setConfig(config);
        String encryptedText = "oOuQJhZQF9JcHz0dba78cw==";   //加密后的密码
        String plainText = standardPBEStringEncryptor.decrypt(encryptedText);
        System.out.println(plainText);
    }

}
3、yml配置文件如下参数(开发环境写入,生产环境不建议配置口令,具体看步骤6)
#低于jasypt3.0.0版本如下:
#加密
jasypt:
  # 盐加密
  encryptor:
    password: secrect

#高于jasypt3.0.0版本如下
jasypt:
  encryptor:
    # 盐加密
    password: secrect
    # 指定加密方式
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

 其中secrect就是加密的口令。

4、将步骤2中根据明文生成的密码替换到yml配置中如下(放入ENC()中):

5、 在spring boot启动类上添加注解开启加密:

     @EnableEncryptableProperties //开启加密注解

6、生产环境不配置yml加密口令,要么什么都不写,要么只写下面:
 

jasypt:
  encryptor:
    # 指定加密方式
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator


将项目打包发布。
发布命令:java -jar xxx.jar --jasypt.encryptor.password=secrect      secrect 就是你的密匙

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐