java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Springboot实现ENC加密

Springboot实现ENC加密的详细流程

作者:364.99°

在项目开发过程中,需要配置数据库连接密码、Redis密码、网盘上传的AK/SK等敏感信息,都需要保存在配置文件里,或者配置中心,这些信息如果泄露,还是会造成一定的困扰,下面这篇文章主要给大家介绍了关于Springboot实现ENC加密的详细流程,需要的朋友可以参考下

1. 为什么要用ENC加密

以下是未经过加密的数据库配置,密码均是采用明文密码,很容易导致数据库泄露。

spring:
 datasource:
  dynamic:
	postgresql:
	 url: jdbc:postgresql://127.0.0.1:5589/mypg?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
	 username: root
	 password: admin          
	 driver-class-name: org.postgresql.Driver 
...

redis:
 ip: www.xxxx.top
 port: 6379
 # 密码
 pass: admin	
 # 最大实例
 max-total: 1024
 # 最大空闲实例
 max-idle: 100
 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。
 max-wait: 10000
 # 超时时间,单位毫秒。
 timeout: 10000

以下是经过ENC加密之后的配置,这样之后,数据库密码安全级别就高了。

spring:
 datasource:
  dynamic:
	postgresql:
	 url: jdbc:postgresql://127.0.0.1:5589/mypg?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
	 username: root
	 password: ENC(2qWZr4WLw8H0nPBzMXBV9WimRfKC3pv5UVGB5mMApbINg2s83VfsYvL7XTWaUR8q)
	 driver-class-name: org.postgresql.Driver 
...

redis:
 ip: www.xxxx.top
 port: 6379
 # 密码
 pass: ENC(2qWZr4WLw8H0nPBzMXBV9WimRfKC3pv5UVGB5mMApbINg2s83VfsYvL7XTWaUR8q)	
 # 最大实例
 max-total: 1024
 # 最大空闲实例
 max-idle: 100
 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。
 max-wait: 10000
 # 超时时间,单位毫秒。
 timeout: 10000

2. jasypt实现ENC加密

1. 实现流程

导入依赖:

        <!-- 配置文件加密 -->
        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>

测试类:

import org.jasypt.encryption.StringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @Author: chenJY
 * @Description:
 * @Date: 2022-11-18 9:19
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class EncryptorTest {
    @Resource
    private StringEncryptor jasyptStringEncryptor;

    @Test
    public void encode() {
        System.out.println( "加密密文:" + jasyptStringEncryptor.encrypt("admin") );
        System.out.println("解密密文:" + jasyptStringEncryptor.decrypt(jasyptStringEncryptor.encrypt("admin")));
    }
}

运行测试类:

注意: 每次运行测试类输出的加密密码都不同,但不影响其解密密文。

将加密密文加入到配置文件中:

spring:
 datasource:
  dynamic:
	postgresql:
	 url: jdbc:postgresql://127.0.0.1:5589/mypg?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
	 username: root
	 password: ENC(2qWZr4WLw8H0nPBzMXBV9WimRfKC3pv5UVGB5mMApbINg2s83VfsYvL7XTWaUR8q)
	 driver-class-name: org.postgresql.Driver 
...

redis:
 ip: www.xxxx.top
 port: 6379
 # 密码
 pass: ENC(2qWZr4WLw8H0nPBzMXBV9WimRfKC3pv5UVGB5mMApbINg2s83VfsYvL7XTWaUR8q)
 # 最大实例
 max-total: 1024
 # 最大空闲实例
 max-idle: 100
 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。
 max-wait: 10000
 # 超时时间,单位毫秒。
 timeout: 10000

重启springboot项目,能正常启动

2. 说明

由于springboot自动配置的特性,导入 jasypt-spring-boot 依赖包之后,不用进行过多配置,就能实现配置文件加密字段自动解密,所以特别方便。

1. 自定义加密秘钥

1. 盐、前缀、后缀

可以在配置文件中自定义一个加密秘钥(盐), 来获取明文密码。

# 加密秘钥
jasypt:
  encryptor:
    password: Chen # 加密时的salt值

自定义加密前缀、后缀: 如果不想使用 ENC来作为加密前缀,那么可以通过配置文件修改:

# 加密秘钥
jasypt:
  encryptor:
    password: Chen
    property:
      prefix: Chen( # 前缀
      suffix: )chen # 后缀

那么,密码的格式如下:

password: Chen(2qWZr4WLw8H0nPBzMXBV9WimRfKC3pv5UVGB5mMApbINg2s83VfsYvL7XTWaUR8q)chen

2. 自定义加密方案

配置类

@Configuration
public class MyEncryptorCfg {
    /**
     * @Description 自定义的加密器配置
     * @author chenJY
     * @date 2022/11/18 9:52
     * @return StringEncryptor
    */
    @Bean(name = "myStringEncryptor")
    public StringEncryptor myStringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("Chen");
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        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;
    }
}

注意1: bean必须重命名,bean默认名是 jasyptStringEncryptor,当我们要自定义加密方案的时候,就必须重命名。

注意2: 需要在配置文件中加入如下配置:

jasypt:
  encryptor:
    bean: myStringEncryptor

并修改测试类:

    @Autowired
    private StringEncryptor myStringEncryptor;

2. 部署方案

密钥(盐值)存储说明: 本身加解密过程都是通过盐值进行处理的,所以正常情况下盐值和加密串是分开存储的。盐值应该放在系统属性、命令行或是环境变量来使用,而不是放在配置文件。

程序启动 命令行参数:

java -jar xxx.jar --jasypt.encryptor.password=Chen &

程序启动 环境变量:

java -jar -Djasypt.encryptor.password=Chen xxx.jar

3. 输出密文的几种方案

优化1.: 上面的写法是直接写死了需要加密的密码,我们可以换一种在配置文件中读取数据库密码的写法,如下:

	import org.jasypt.encryption.StringEncryptor;
	import org.junit.Test;
	import org.junit.runner.RunWith;
	import org.springframework.boot.test.context.SpringBootTest;
	import org.springframework.test.context.junit4.SpringRunner;
	
	import javax.annotation.Resource;
	
	/**
	 * @Author: chenJY
	 * @Description:
	 * @Date: 2022-11-18 9:19
	 */
	@SpringBootTest
	@RunWith(SpringRunner.class)
	public class EncryptorTest {
		@Resource
    	private ApplicationContext applicationContext;

	    @Resource
	    private StringEncryptor jasyptStringEncryptor;
	
	    @Test
	    public void encode() {
	        Environment environment = applicationContext.getEnvironment();
        	String password = environment.getProperty("spring.datasource.dynamic.postgresql.password");
	        System.out.println( "加密密文:" + jasyptStringEncryptor.encrypt(password) );
	        System.out.println("解密密文:" + jasyptStringEncryptor.decrypt(jasyptStringEncryptor.encrypt(password)));
	    }
	}

优化2: 重写启动类的run(),实现每次启动项目都会输出一次加密密文

import org.jasypt.encryption.StringEncryptor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;

@SpringBootApplication
public class TestDemoApplication implements CommandLineRunner{

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private StringEncryptor jasyptStringEncryptor;

    public static void main(String[] args) {
        SpringApplication.run(TestDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Environment environment = applicationContext.getEnvironment();
        String pwd = environment.getProperty("spring.datasource.dynamic.postgresql.password");
        // 打印解密后的结果
        System.out.println( "加密密文:" + jasyptStringEncryptor.encrypt(pwd) );
    }
}

总结

到此这篇关于Springboot实现ENC加密的详细流程的文章就介绍到这了,更多相关Springboot实现ENC加密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文