前后端API交互加密解密(js、Java)
⼀、前⾔
前后端分离的开发⽅式,我们以接⼝为标准来进⾏推动,定义好接⼝,各⾃开发⾃⼰的功能,最后进⾏联调整合。⽆论是开发原⽣的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调⽤后端提供的接⼝来进⾏业务交互。
⽹页或者app,只要抓下包就可以清楚的知道这个请求获取到的数据,这样的接⼝对爬⾍⼯程师来说是⼀种福⾳,要抓你的数据简直轻⽽易举。
数据的安全性⾮常重要,特别是⽤户相关的信息,稍有不慎就会被不法分⼦盗⽤,所以我们对这块要⾮常重视,容不得马虎。
⼆、如何保证API调⽤时数据的安全性?
1、通信使⽤https
2、请求签名,防⽌参数被篡改
3、⾝份确认机制,每次请求都要验证是否合法
4、APP中使⽤ssl pinning防⽌抓包操作
5、对所有请求和响应都进⾏加解密操作
6、等等⽅案…….
三、对所有请求和响应都进⾏加解密操作
⽅案有很多种,当你做的越多,也就意味着安全性更⾼,今天我跟⼤家来介绍⼀下对所有请求和响应都进⾏加解密操作的⽅案,即使能抓包,即使能调⽤我的接⼝,但是我返回的数据是加密的,只要加密算法够安全,你得到了我的加密内容也对我没什么影响。
像这种⼯作最好做成统⼀处理的,你不能让每个开发都去关注这件事情,如果让每个开发去关注这件事情就很⿇烦了,返回数据时还得⼿动调⽤下加密的⽅法,接收数据后还得调⽤下解密的⽅法。
为此,我基于Spring Boot封装了⼀个Starter, 内置了AES加密算法。GitHub地址如下:
js代码加密软件先来看看怎么使⽤,可以下载源码,然后引⼊即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:
增加加密的key配置:
为了考虑通⽤性,不会对所有请求都执⾏加解密,基于注解来做控制
响应数据需要加密的话,就在Controller的⽅法上加@Encrypt注解即可。
当我们访问/list接⼝时,返回的数据就是加密之后base64编码的格式。
还有⼀种操作就是前段提交的数据,分为2种情况,⼀种是get请求,这种暂时没处理,后⾯再考虑,⽬前只处理的post请求,基于json格式提交的⽅式,也就是说后台需要⽤@RequestBody接收数据才⾏, 需要解密的操作我们加上@Decrypt注解即可。
加了@Decrypt注解后,前端提交的数据需要按照AES加密算法,进⾏加密,然后提交到后端,后端这边会⾃动解密,然后再映射到参数对象中。
上⾯讲解的都是后端的代码,前端使⽤的话我们以js来讲解,当然你也能⽤别的语⾔来做,如果是原⽣的安卓app也是⽤java代码来处理。
前端需要做的就2件事情:
1、统⼀处理数据的响应,在渲染到页⾯之前进⾏解密操作
2、当有POST请求的数据发出时,统⼀加密
js加密⽂件请参考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js
我们以axios来作为请求数据的框架,⽤axios的来统⼀处理加密解密操作
⾸先还是要封装⼀个js加解密的类,需要注意的是加密的key需要和后台的对上,不然⽆法相互解密,代码如下:
axios中统⼀处理代码:
到此为⽌,我们就为整个前后端交互的通信做了⼀个加密的操作,只要加密的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算法⽣成⼀对公钥和私钥,我们简称为pubk
ey2,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导⼊⾃动配置类
EncryptAutoConfiguration中配置请求和响应的处理类,⽤的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring 中对请求进⾏统计处理⽐较⽅便。如果还要更底层去封装那就要从servlet那块去处理了。
通过RequestBodyAdvice和ResponseBodyAdvice就可以对请求响应做处理了,⼤概的原理就是这么多了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。