SpingBoot加解密项⽬spring-boot-starter-encrypt操作
Spring Boot封装了⼀个Starter, 内置了AES加密算法。GitHub地址如下:
先来看看怎么使⽤,可以下载源码,然后引⼊即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:
@EnableEncrypt
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
增加加密的key配置:
为了考虑通⽤性,不会对所有请求都执⾏加解密,基于注解来做控制
响应数据需要加密的话,就在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 = Latin1.parse('abcdef0123456789');
var iv = Latin1.parse('abcdef0123456789');
// 加密
function EncryptData(data) {
var srcs = Utf8.parse(data);
var encrypted = pt(srcs, key, {
mode : de.ECB,
padding : CryptoJS.pad.Pkcs7
});
String();
}
// 解密
function DecryptData(data) {
var stime = new Date().getTime();
var decrypt = CryptoJS.AES.decrypt(data, key, {
mode : de.ECB,
padding : CryptoJS.pad.Pkcs7
});
var result = JSON.Utf8.stringify(decrypt).toString());
var etime = new Date().getTime();
console.log("DecryptData Time:" + (etime - stime));
return result;
}springboot推荐算法
axios中统⼀处理代码:
// 添加请求
quest.use(function (config) {
/
/ 对所有POST请加密,必须是json数据提交,不⽀持表单
if (hod == "post") {
config.data = EncryptData(JSON.stringify(config.data));
}
return config;
}, function (error) {
ject(error);
});
// 添加响应
sponse.use(function (response) {
// 后端返回字符串表⽰需要解密操作
if(typeof(response.data) == "string"){
response.data = DecryptData(response.data);
}
return response;
}, function (error) {
ject(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就可以对请求响应做处理了,⼤概的原理就是这么多了。
作者:猿天地
链接:juejin.im/post/5b149754f265da6e155d4748
来源:掘⾦
著作权归作者所有。商业转载请联系作者获得授权,⾮商业转载请注明出处。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论