SpingBoot加解密项目spring-boot-starter-encrypt操作

本文介绍如何在SpringBoot项目中使用内置的Starter实现AES加密算法,包括前后端加解密操作及动态获取加密key的方法。

Spring Boot封装了一个Starter, 内置了AES加密算法。GitHub地址如下:

spring-boot-starter-encrypt

先来看看怎么使用,可以下载源码,然后引入即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:

@EnableEncrypt
@SpringBootApplication
public class App {
	
    public static void main(String[] args) {
		SpringApplication.run(App.class, args);
    }
}

增加加密的key配置:

spring.encrypt.key=abcdef0123456789
spring.encrypt.debug=false
  • spring.encrypt.key:加密key,必须是16位
  • spring.encrypt.debug:是否开启调试模式,默认为false,如果为true则不启用加解密操作

为了考虑通用性,不会对所有请求都执行加解密,基于注解来做控制

响应数据需要加密的话,就在Controller的方法上加@Encrypt注解即可。

@Encrypt
@GetMapping("/list")
public Response queryNews(String city) {
	return Response.ok(city);
}

当我们访问/list接口时,返回的数据就是加密之后base64编码的格式。

还有一种操作就是前段提交的数据,分为2种情况,一种是get请求,这种暂时没处理,后面再考虑,目前只处理的post请求,基于json格式提交的方式,也就是说后台需要用@RequestBody接收数据才行, 需要解密的操作我们加上@Decrypt注解即可。

@Decrypt
@PostMapping("/save")
public Response savePageLog(@RequestBody PageLogParam logParam, HttpServletRequest request) {
	pageLogService.save(logParam);
	return Response.ok();
}

加了@Decrypt注解后,前端提交的数据需要按照AES加密算法,进行加密,然后提交到后端,后端这边会自动解密,然后再映射到参数对象中。

上面讲解的都是后端的代码,前端使用的话我们以js来讲解,当然你也能用别的语言来做,如果是原生的安卓app也是用java代码来处理。

前端需要做的就2件事情:

  1. 统一处理数据的响应,在渲染到页面之前进行解密操作
  2. 当有POST请求的数据发出时,统一加密

js加密文件请参考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js

我们以axios来作为请求数据的框架,用axios的拦截器来统一处理加密解密操作

首先还是要封装一个js加解密的类,需要注意的是加密的key需要和后台的对上,不然无法相互解密,代码如下:

var key  = CryptoJS.enc.Latin1.parse('abcdef0123456789');
var iv   = CryptoJS.enc.Latin1.parse('abcdef0123456789');

// 加密
function EncryptData(data) {
	var srcs = CryptoJS.enc.Utf8.parse(data);
	var encrypted = CryptoJS.AES.encrypt(srcs, key, {
		mode : CryptoJS.mode.ECB,
		padding : CryptoJS.pad.Pkcs7
	});
	return encrypted.toString();
}

// 解密
function DecryptData(data) {
	var stime = new Date().getTime();
	var decrypt = CryptoJS.AES.decrypt(data, key, {
		mode : CryptoJS.mode.ECB,
		padding : CryptoJS.pad.Pkcs7
	});
	var result = JSON.parse(CryptoJS.enc.Utf8.stringify(decrypt).toString());
	var etime = new Date().getTime();
	console.log("DecryptData Time:" + (etime - stime));
	return result;
}

axios拦截器中统一处理代码:

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
	// 对所有POST请加密,必须是json数据提交,不支持表单
	if (config.method == "post") {
		config.data = EncryptData(JSON.stringify(config.data));
	}
    return config;
  }, function (error) {
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
	// 后端返回字符串表示需要解密操作
	if(typeof(response.data) == "string"){
		response.data = DecryptData(response.data);
	}
    return response;
  }, function (error) {
	return Promise.reject(error);
});

到此为止,我们就为整个前后端交互的通信做了一个加密的操作,只要加密的key不泄露,别人得到你的数据也没用,问题是如何保证key不泄露呢?

服务端的安全性较高,可以存储在数据库中或者配置文件中,毕竟在我们自己的服务器上,最危险的其实就时前端了,app还好,可以打包,但是要防止反编译等等问题。

如果是webapp则可以依赖于js加密来实现,下面我给大家介绍一种动态获取加密key的方式,只不过实现起来比较复杂,我们不上代码,只讲思路:

加密算法有对称加密和非对称加密,AES是对称加密,RSA是非对称加密。之所以用AES加密数据是因为效率高,RSA运行速度慢,可以用于签名操作。

我们可以用这2种算法互补,来保证安全性,用RSA来加密传输AES的秘钥,用AES来加密数据,两者相互结合,优势互补。

其实大家理解了HTTPS的原理的话对于下面的内容应该是一看就懂的,HTTPS比HTTP慢的原因都是因为需要让客户端与服务器端安全地协商出一个对称加密算法。剩下的就是通信时双方使用这个对称加密算法进行加密解密。

  1. 客户端启动,发送请求到服务端,服务端用RSA算法生成一对公钥和私钥,我们简称为pubkey1,prikey1,将公钥pubkey1返回给客户端。
  2. 客户端拿到服务端返回的公钥pubkey1后,自己用RSA算法生成一对公钥和私钥,我们简称为pubkey2,prikey2,并将公钥pubkey2通过公钥pubkey1加密,加密之后传输给服务端。
  3. 此时服务端收到客户端传输的密文,用私钥prikey1进行解密,因为数据是用公钥pubkey1加密的,通过解密就可以得到客户端生成的公钥pubkey2
  4. 然后自己在生成对称加密,也就是我们的AES,其实也就是相对于我们配置中的那个16的长度的加密key,生成了这个key之后我们就用公钥pubkey2进行加密,返回给客户端,因为只有客户端有pubkey2对应的私钥prikey2,只有客户端才能解密,客户端得到数据之后,用prikey2进行解密操作,得到AES的加密key,最后就用加密key进行数据传输的加密,至此整个流程结束。

spring-boot-starter-encrypt原理

最后我们来简单的介绍下spring-boot-starter-encrypt的原理吧,也让大家能够理解为什么Spring Boot这么方便,只需要简单的配置一下就可以实现很多功能。

启动类上的@EnableEncrypt注解是用来开启功能的,通过@Import导入自动配置类

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EncryptAutoConfiguration.class})
public @interface EnableEncrypt {

}

EncryptAutoConfiguration中配置请求和响应的处理类,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中对请求进行统计处理比较方便。如果还要更底层去封装那就要从servlet那块去处理了。

@Configuration
@Component
@EnableAutoConfiguration
@EnableConfigurationProperties(EncryptProperties.class)
public class EncryptAutoConfiguration {

	/**
	 * 配置请求解密
	 * @return
	 */
	@Bean
	public EncryptResponseBodyAdvice encryptResponseBodyAdvice() {
		return new EncryptResponseBodyAdvice();
	}
	
	/**
	 * 配置请求加密
	 * @return
	 */
	@Bean
	public EncryptRequestBodyAdvice encryptRequestBodyAdvice() {
		return new EncryptRequestBodyAdvice();
	}
	
}

通过RequestBodyAdvice和ResponseBodyAdvice就可以对请求响应做处理了,大概的原理就是这么多了。


作者:猿天地
链接:https://juejin.im/post/5b149754f265da6e155d4748
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Spring Boot 项目中使用 `jasypt-spring-boot-starter`(版本 1.9)可以实现对配置文件中的敏感数据进行加密处理,例如数据库密码、API 密钥等。以下是完整的配置方法和使用示例。 ### 3.1 添加依赖 首先,在 `pom.xml` 文件中添加 `jasypt-spring-boot-starter` 的依赖,确保版本为 `1.9.x`: ```xml <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>1.9.3</version> </dependency> ``` 该依赖会自动启用 Jasypt 对整个 Spring 环境中的属性进行加密支持,包括 `application.properties`、`application.yml`、系统环境变量等[^2]。 ### 3.2 配置加密密钥 Jasypt 使用一个密钥(password)来加密和解密数据。为了避免密钥泄露,**密钥不应硬编码在配置文件中**,而应通过命令行参数或环境变量传入。 启动应用时,可以通过以下方式指定密钥: ```bash java -jar your-application.jar --jasypt.encryptor.password=your-secret-key ``` 或者通过环境变量设置: ```bash export JASYPT_ENCRYPTOR_PASSWORD=your-secret-key ``` ### 3.3 加密敏感属性 使用 Jasypt 提供的工具类对敏感信息进行加密。例如,加密数据库密码: ```java import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; public class JasyptEncryptor { public static void main(String[] args) { StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); encryptor.setPassword("your-secret-key"); // 设置密钥 String encrypted = encryptor.encrypt("your-db-password"); System.out.println("Encrypted: " + encrypted); } } ``` 输出结果将是一个加密字符串,例如: ``` Encrypted: ENC(9xgT8zZ123456789) ``` ### 3.4 在配置文件中使用加密值 将加密后的值插入到 `application.properties` 或 `application.yml` 文件中,并使用 `ENC()` 包裹: #### application.properties 示例: ```properties spring.datasource.password=ENC(9xgT8zZ123456789) ``` #### application.yml 示例: ```yaml spring: datasource: password: ENC(9xgT8zZ123456789) ``` Spring Boot 会自动识别 `ENC()` 标记的值,并通过 Jasypt 进行解密[^1]。 ### 3.5 自定义加密器(可选) 如果需要自定义加密算法,可以在 `application.properties` 中配置: ```properties jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES jasypt.encryptor.key-obtention-iterations=1000 ``` ### 3.6 使用示例:数据库连接配置 以下是一个完整的数据库连接配置示例,其中密码为加密形式: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: ENC(9xgT8zZ123456789) driver-class-name: com.mysql.cj.jdbc.Driver ``` 启动应用时传入密钥: ```bash java -jar your-application.jar --jasypt.encryptor.password=your-secret-key ``` 应用会自动解密 `ENC()` 包裹的密码,并正常连接数据库[^4]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值