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.: 上面的写法是直接写死了需要加密的密码,我们可以换一种在配置文件中读取数据库密码的写法,如下:文章来源:https://www.toymoban.com/news/detail-469427.html
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(),实现每次启动项目都会输出一次加密密文文章来源地址https://www.toymoban.com/news/detail-469427.html
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加密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!