Spring Boot2.X 配置文件自动解密读取

举报
福州司马懿 发表于 2021/11/19 03:48:59 2021/11/19
【摘要】 第三方库 jasypt 要实现该功能,我们要借助一个 Github 的第三方库 com.github.ulisesbocchio » jasypt-spring-boot-starter,Github地...

第三方库 jasypt

要实现该功能,我们要借助一个 Github 的第三方库 com.github.ulisesbocchio » jasypt-spring-boot-starter,Github地址为 https://github.com/ulisesbocchio/jasypt-spring-boot

Maven 地址如下:https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter
在这里插入图片描述点击最新的版本号,会列出 maven 或 gradle 的依赖方式,拷贝即可
在这里插入图片描述

maven 的依赖方式

<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

gradle 的依赖方式

// https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter
compile group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '2.1.2'

  
 
  • 1
  • 2

jasypt 官网

http://www.jasypt.org/cli.html,可以查到它所支持的摘要算法和加密方式

在这里插入图片描述

摘要算法

  • MD2
  • MD5
  • SHA
  • SHA-256
  • SHA-384
  • SHA-512

加密方式

  • PBEWITHMD5ANDDES
  • PBEWITHMD5ANDTRIPLEDES
  • PBEWITHSHA1ANDDESEDE
  • PBEWITHSHA1ANDRC2_40

jsypt 的仓库路径

在 maven 中添加引用之后,jsypt 会自动被下载到 m2 仓库中,默认的地址为 C:\Users\【用户名】.m2\repository\org\jasypt\jasypt\1.9.3
在这里插入图片描述

命令行加密数据

java -cp 与 java -jar 的区别

  • java -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类
  • java -jar 执行的适合,会用到 jar 包里面的 META-INF\MANIFEST.MF 文件,在该文件中,有一个叫Main-Class的参数,它说明了java -jar命令执行的类
cd C:\Users\【用户名】\.m2\repository\org\jasypt\jasypt\1.9.3

java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=【待加密的数据】 password=【密码】algorithm=PBEWithMD5AndDES

  
 
  • 1
  • 2
  • 3

在这里插入图片描述

实现自动解密

默认属性加密

创建包含加密数据的 yaml 文件

在 resources 的 config 目录下创建一个 encrypt.xml 文件(文件名随意),内容如下

spring:
 datasource:
  url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=mydatabase
  username: bob
  password: ENC(eGm+abBtq2NXGt7FZ3SDoEPpHaQ2OOpXZ/L16aSfBMc=)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

ENC() 表示 括号内部的内容是加密的,spring boot 在初始化时会自动将其解密(括号内的内容用的就是我们之前通过命令行加密后的值)

启用加密配置文件

  • @EnableEncryptableProperties 表示启用加密配置文件
  • @EncryptablePropertySource 用来设置加密配置文件的路径
  • @EncryptablePropertySources 如果有多个加密配置文件,则用花括号括起来,中间用逗号隔开每一个@EncryptablePropertySource

注意:只要有用到加密配置文件,前两者都不能省

@EnableEncryptableProperties
//@EncryptablePropertySource("classpath:/config/encrypt.yml")
@EncryptablePropertySource(value="classpath:/config/encrypt.yml")
//@EncryptablePropertySources({@EncryptablePropertySource("classpath:/config/encrypt.yml")})
public class EncryptionPropertyConfig { …… }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

添加一个配置类,对加密器进行配置

@Configuration
@EnableEncryptableProperties
@EncryptablePropertySource("classpath:/config/encrypt.yml")
public class EncryptionPropertyConfig {
	//这个bean的名字也不能随意更改,否则编译不过
	@Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
		//集中式PBE字符串加密器
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        //简单字符串形式的PBC配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        //设置加密密码(大小写敏感),密码错误将导致程序异常
        config.setPassword("YourPassword");
        //设置加密算法
        config.setAlgorithm("PBEWithMD5AndDES");
        //设置获取加密密钥的哈希迭代次数
        config.setKeyObtentionIterations("1000");
        //设置线程池大小
        config.setPoolSize("1");
        //设置加密器的提供者
        config.setProviderName("SunJCE");
        //设置加盐的类名
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        //设置初始向量IV生成器的类名
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        //设置字节数组以base64格式输出
        config.setStringOutputType("base64");
        //将对应的配置设置到密码器上
        encryptor.setConfig(config);
        return encryptor;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

添加一个访问控制器,当访问某个地址时,打印该变量

@RestController
public class TestController {
	@Value("${spring.datasource.password}")
	private String password;

	@GetMapping("/testValue")
	public String testValue() {
		System.out.println(password);
		return "";
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

改变加密标志前缀和后缀

默认的加密前缀是 “ENC(” ,后缀是")"。但有的时候我们需要自定义,方法是在 application.yml 后面添加一段

jasypt:
 encryptor:
  property:
   prefix: "ENC@["
   suffix: "]"

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

这样,加密前缀就改为了 “ENC@[”,而后缀就改为了 “]”,修改配置文件后重启即可生效

spring:
 datasource:
  url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=mydatabase
  username: bob
  password: ENC@[eGm+abBtq2NXGt7FZ3SDoEPpHaQ2OOpXZ/L16aSfBMc=]

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

自定义属性解密方式

@Configuration
@EnableEncryptableProperties
@EncryptablePropertySource("classpath:/config/encrypt.yml")
public class EncryptionPropertyConfig {
	// 加密属性前缀
	private static final String PREFIX = "ENC@[";
	// 密钥
	private static String PASSWORD = "YourPassword";

	//同样名字不能随意修改,否则编译不通过
	@Bean(name = "encryptablePropertyResolver")
	public EncryptablePropertyResolver encryptablePropertyResolver() {
		return new MyEncryptablePropertyResolver(PREFIX, PASSWORD);
	}

	private static class MyEncryptablePropertyResolver implements EncryptablePropertyResolver {

		private final String prefix;
		//PBE字符串加密器
		private final PooledPBEStringEncryptor encryptor;

		public MyEncryptablePropertyResolver(String prefix, String password) {
			this.prefix = prefix;
			// 集中式PBE字符串加密器
			encryptor = new PooledPBEStringEncryptor();
			// 简单字符串形式的PBC配置
			SimpleStringPBEConfig config = new SimpleStringPBEConfig();
			// 设置加密密码(大小写敏感),密码错误将导致程序异常
			config.setPassword("YourPassword");
			// 设置加密算法
			config.setAlgorithm("PBEWithMD5AndDES");
			// 设置获取加密密钥的哈希迭代次数
			config.setKeyObtentionIterations("1000");
			// 设置线程池大小
			config.setPoolSize("1");
			// 设置加密器的提供者
			config.setProviderName("SunJCE");
			// 设置加盐的类名
			config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
			// 设置初始向量IV生成器的类名
			config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
			// 设置字节数组以base64格式输出
			config.setStringOutputType("base64");
			// 将对应的配置设置到密码器上
			encryptor.setConfig(config);
		}

		/**
		依次解析每个属性的值。判断是否是加密字段,如果是则进行解密
		解密函数可以用 jsypt 自带的解密方式,也可以用自己写的一套加解密规则
		*/
		@Override
		public String resolvePropertyValue(String value) {
			System.out.println("resolvePropertyValue : " + value);
			if (!StringUtils.isEmpty(value) && value.startsWith(prefix)) {
				String encValue = value.substring(prefix.length());
				String rawValue = encryptor.decrypt(value.substring(prefix.length()));
				return rawValue;
			}
			return value;
		}
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

在这里插入图片描述

从结果可以看出,调用 resolvePropertyValue 函数之后,会对返回值和参数进行比较,如果两者不同还会再调用一次 resolvePropertyValue ,也就是说,加密支持递归加密。

文章来源: blog.csdn.net,作者:福州-司马懿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/chy555chy/article/details/101213622

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。