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) );
    }
}
  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Spring Boot是一个开源的Java框架,可帮助开发者更快速地构建应用程序。Jasypt3是Spring Boot中一种常用的加密库,可用于加密敏感数据,如数据库密码。下面简要介绍如何使用Spring Boot和Jasypt3来加密数据库密码: 1. 添加依赖:在pom.xml中添加Jasypt3的依赖,如下所示: ```xml <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> ``` 2. 配置加密算法和密钥: 在Spring Boot的配置文件(application.properties或application.yml)中添加以下配置: ```properties jasypt.encryptor.algorithm=算法 jasypt.encryptor.password=密钥 ``` 3. 加密数据库密码: 在配置文件中使用Jasypt3提供的加密语法将数据库密码进行加密。例如,假设我们要加密的密码是"password",可以使用以下语法: ```properties encryptor.encrypt(密码) ``` 4. 使用加密的密码: 在项目中的数据源配置文件(如application.properties)中,使用加密后的密码。例如: ```properties spring.datasource.username=用户名 spring.datasource.password=ENC(加密的密码) ``` 5. 运行应用程序: 启动Spring Boot应用程序,它将自动使用配置的密钥解密密码,然后使用解密后的密码连接数据库。 通过以上步骤,我们可以使用Spring Boot和Jasypt3来实现数据库密码的加密。这样可以保护敏感数据的安全性,同时提供了一种方便的方法来管理加密密钥和加密算法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

364.99°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值