自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前后端API交互如何保證數(shù)據(jù)安全性?

安全 數(shù)據(jù)安全
前后端分離的開發(fā)方式,我們以接口為標(biāo)準(zhǔn)來進(jìn)行推動(dòng),定義好接口,各自開發(fā)自己的功能,最后進(jìn)行聯(lián)調(diào)整合。無論是開發(fā)原生的APP還是webapp還是PC端的軟件,只要是前后端分離的模式,就避免不了調(diào)用后端提供的接口來進(jìn)行業(yè)務(wù)交互。

 

前言

前后端分離的開發(fā)方式,我們以接口為標(biāo)準(zhǔn)來進(jìn)行推動(dòng),定義好接口,各自開發(fā)自己的功能,***進(jìn)行聯(lián)調(diào)整合。無論是開發(fā)原生的APP還是webapp還是PC端的軟件,只要是前后端分離的模式,就避免不了調(diào)用后端提供的接口來進(jìn)行業(yè)務(wù)交互。

網(wǎng)頁或者app,只要抓下包就可以清楚的知道這個(gè)請(qǐng)求獲取到的數(shù)據(jù),這樣的接口對(duì)爬蟲工程師來說是一種福音,要抓你的數(shù)據(jù)簡直輕而易舉。

數(shù)據(jù)的安全性非常重要,特別是用戶相關(guān)的信息,稍有不慎就會(huì)被不法分子盜用,所以我們對(duì)這塊要非常重視,容不得馬虎。

如何保證API調(diào)用時(shí)數(shù)據(jù)的安全性?

  1. 通信使用https
  2. 請(qǐng)求簽名,防止參數(shù)被篡改
  3. 身份確認(rèn)機(jī)制,每次請(qǐng)求都要驗(yàn)證是否合法
  4. APP中使用ssl pinning防止抓包操作
  5. 對(duì)所有請(qǐng)求和響應(yīng)都進(jìn)行加解密操作
  6. 等等方案.......

對(duì)所有請(qǐng)求和響應(yīng)都進(jìn)行加解密操作

方案有很多種,當(dāng)你做的越多,也就意味著安全性更高,今天我跟大家來介紹一下對(duì)所有請(qǐng)求和響應(yīng)都進(jìn)行加解密操作的方案,即使能抓包,即使能調(diào)用我的接口,但是我返回的數(shù)據(jù)是加密的,只要加密算法夠安全,你得到了我的加密內(nèi)容也對(duì)我沒什么影響。

像這種工作***做成統(tǒng)一處理的,你不能讓每個(gè)開發(fā)都去關(guān)注這件事情,如果讓每個(gè)開發(fā)去關(guān)注這件事情就很麻煩了,返回?cái)?shù)據(jù)時(shí)還得手動(dòng)調(diào)用下加密的方法,接收數(shù)據(jù)后還得調(diào)用下解密的方法。

為此,我基于Spring Boot封裝了一個(gè)Starter, 內(nèi)置了AES加密算法。GitHub地址如下:

github.com/yinjihuan/s…

先來看看怎么使用,可以下載源碼,然后引入即可,然后在啟動(dòng)類上增加@EnableEncrypt注解開啟加解密操作:

  1. @EnableEncrypt 
  2. @SpringBootApplication 
  3. public class App { 
  4.      
  5.     public static void main(String[] args) { 
  6.         SpringApplication.run(App.class, args); 
  7.     } 

增加加密的key配置:

  1. spring.encrypt.key=abcdef0123456789 
  2. spring.encrypt.debug=false 
  • spring.encrypt.key:加密key,必須是16位
  • spring.encrypt.debug:是否開啟調(diào)試模式,默認(rèn)為false,如果為true則不啟用加解密操作

為了考慮通用性,不會(huì)對(duì)所有請(qǐng)求都執(zhí)行加解密,基于注解來做控制

響應(yīng)數(shù)據(jù)需要加密的話,就在Controller的方法上加@Encrypt注解即可。

  1. @Encrypt 
  2. @GetMapping("/list"
  3. public Response queryNews(String city) { 
  4.     return Response.ok(city); 

當(dāng)我們訪問/list接口時(shí),返回的數(shù)據(jù)就是加密之后base64編碼的格式。

還有一種操作就是前段提交的數(shù)據(jù),分為2種情況,一種是get請(qǐng)求,這種暫時(shí)沒處理,后面再考慮,目前只處理的post請(qǐng)求,基于json格式提交的方式,也就是說后臺(tái)需要用@RequestBody接收數(shù)據(jù)才行, 需要解密的操作我們加上@Decrypt注解即可。

  1. @Decrypt 
  2. @PostMapping("/save"
  3. public Response savePageLog(@RequestBody PageLogParam logParam, HttpServletRequest request) { 
  4.     pageLogService.save(logParam); 
  5.     return Response.ok(); 

加了@Decrypt注解后,前端提交的數(shù)據(jù)需要按照AES加密算法,進(jìn)行加密,然后提交到后端,后端這邊會(huì)自動(dòng)解密,然后再映射到參數(shù)對(duì)象中。

上面講解的都是后端的代碼,前端使用的話我們以js來講解,當(dāng)然你也能用別的語言來做,如果是原生的安卓app也是用java代碼來處理。

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

  1. 統(tǒng)一處理數(shù)據(jù)的響應(yīng),在渲染到頁面之前進(jìn)行解密操作
  2. 當(dāng)有POST請(qǐng)求的數(shù)據(jù)發(fā)出時(shí),統(tǒng)一加密

js加密文件請(qǐng)參考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js

我們以axios來作為請(qǐng)求數(shù)據(jù)的框架,用axios的攔截器來統(tǒng)一處理加密解密操作

首先還是要封裝一個(gè)js加解密的類,需要注意的是加密的key需要和后臺(tái)的對(duì)上,不然無法相互解密,代碼如下:

  1. var key  = CryptoJS.enc.Latin1.parse('abcdef0123456789'); 
  2. var iv   = CryptoJS.enc.Latin1.parse('abcdef0123456789'); 
  3.  
  4. // 加密 
  5. function EncryptData(data) { 
  6.     var srcs = CryptoJS.enc.Utf8.parse(data); 
  7.     var encrypted = CryptoJS.AES.encrypt(srcs, key, { 
  8.         mode : CryptoJS.mode.ECB, 
  9.         padding : CryptoJS.pad.Pkcs7 
  10.     }); 
  11.     return encrypted.toString(); 
  12.  
  13. // 解密 
  14. function DecryptData(data) { 
  15.     var stime = new Date().getTime(); 
  16.     var decrypt = CryptoJS.AES.decrypt(data, key, { 
  17.         mode : CryptoJS.mode.ECB, 
  18.         padding : CryptoJS.pad.Pkcs7 
  19.     }); 
  20.     var result = JSON.parse(CryptoJS.enc.Utf8.stringify(decrypt).toString()); 
  21.     var etime = new Date().getTime(); 
  22.     console.log("DecryptData Time:" + (etime - stime)); 
  23.     return result; 

axios攔截器中統(tǒng)一處理代碼:

  1. // 添加請(qǐng)求攔截器 
  2. axios.interceptors.request.use(function (config) { 
  3.     // 對(duì)所有POST請(qǐng)加密,必須是json數(shù)據(jù)提交,不支持表單 
  4.     if (config.method == "post") { 
  5.         config.data = EncryptData(JSON.stringify(config.data)); 
  6.     } 
  7.     return config; 
  8.   }, function (error) { 
  9.     return Promise.reject(error); 
  10. }); 
  11.  
  12. // 添加響應(yīng)攔截器 
  13. axios.interceptors.response.use(function (response) { 
  14.     // 后端返回字符串表示需要解密操作 
  15.     if(typeof(response.data) == "string"){ 
  16.         response.data = DecryptData(response.data); 
  17.     } 
  18.     return response; 
  19.   }, function (error) { 
  20.     return Promise.reject(error); 
  21. }); 

到此為止,我們就為整個(gè)前后端交互的通信做了一個(gè)加密的操作,只要加密的key不泄露,別人得到你的數(shù)據(jù)也沒用,問題是如何保證key不泄露呢?

服務(wù)端的安全性較高,可以存儲(chǔ)在數(shù)據(jù)庫中或者配置文件中,畢竟在我們自己的服務(wù)器上,最危險(xiǎn)的其實(shí)就時(shí)前端了,app還好,可以打包,但是要防止反編譯等等問題。

如果是webapp則可以依賴于js加密來實(shí)現(xiàn),下面我給大家介紹一種動(dòng)態(tài)獲取加密key的方式,只不過實(shí)現(xiàn)起來比較復(fù)雜,我們不上代碼,只講思路:

加密算法有對(duì)稱加密和非對(duì)稱加密,AES是對(duì)稱加密,RSA是非對(duì)稱加密。之所以用AES加密數(shù)據(jù)是因?yàn)樾矢?,RSA運(yùn)行速度慢,可以用于簽名操作。

我們可以用這2種算法互補(bǔ),來保證安全性,用RSA來加密傳輸AES的秘鑰,用AES來加密數(shù)據(jù),兩者相互結(jié)合,優(yōu)勢互補(bǔ)。

其實(shí)大家理解了HTTPS的原理的話對(duì)于下面的內(nèi)容應(yīng)該是一看就懂的,HTTPS比HTTP慢的原因都是因?yàn)樾枰尶蛻舳伺c服務(wù)器端安全地協(xié)商出一個(gè)對(duì)稱加密算法。剩下的就是通信時(shí)雙方使用這個(gè)對(duì)稱加密算法進(jìn)行加密解密。

  1. 客戶端啟動(dòng),發(fā)送請(qǐng)求到服務(wù)端,服務(wù)端用RSA算法生成一對(duì)公鑰和私鑰,我們簡稱為pubkey1,prikey1,將公鑰pubkey1返回給客戶端。
  2. 客戶端拿到服務(wù)端返回的公鑰pubkey1后,自己用RSA算法生成一對(duì)公鑰和私鑰,我們簡稱為pubkey2,prikey2,并將公鑰pubkey2通過公鑰pubkey1加密,加密之后傳輸給服務(wù)端。
  3. 此時(shí)服務(wù)端收到客戶端傳輸?shù)拿芪?,用私鑰prikey1進(jìn)行解密,因?yàn)閿?shù)據(jù)是用公鑰pubkey1加密的,通過解密就可以得到客戶端生成的公鑰pubkey2
  4. 然后自己在生成對(duì)稱加密,也就是我們的AES,其實(shí)也就是相對(duì)于我們配置中的那個(gè)16的長度的加密key,生成了這個(gè)key之后我們就用公鑰pubkey2進(jìn)行加密,返回給客戶端,因?yàn)橹挥锌蛻舳擞衟ubkey2對(duì)應(yīng)的私鑰prikey2,只有客戶端才能解密,客戶端得到數(shù)據(jù)之后,用prikey2進(jìn)行解密操作,得到AES的加密key,***就用加密key進(jìn)行數(shù)據(jù)傳輸?shù)募用?,至此整個(gè)流程結(jié)束。

spring-boot-starter-encrypt原理

***我們來簡單的介紹下spring-boot-starter-encrypt的原理吧,也讓大家能夠理解為什么Spring Boot這么方便,只需要簡單的配置一下就可以實(shí)現(xiàn)很多功能。

啟動(dòng)類上的@EnableEncrypt注解是用來開啟功能的,通過@Import導(dǎo)入自動(dòng)配置類

  1. @Target({ElementType.TYPE}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Documented 
  4. @Inherited 
  5. @Import({EncryptAutoConfiguration.class}) 
  6. public @interface EnableEncrypt { 
  7.  

EncryptAutoConfiguration中配置請(qǐng)求和響應(yīng)的處理類,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中對(duì)請(qǐng)求進(jìn)行統(tǒng)計(jì)處理比較方便。如果還要更底層去封裝那就要從servlet那塊去處理了。

  1. @Configuration 
  2. @Component 
  3. @EnableAutoConfiguration 
  4. @EnableConfigurationProperties(EncryptProperties.class) 
  5. public class EncryptAutoConfiguration { 
  6.  
  7.     /** 
  8.      * 配置請(qǐng)求解密 
  9.      * @return 
  10.      */ 
  11.     @Bean 
  12.     public EncryptResponseBodyAdvice encryptResponseBodyAdvice() { 
  13.         return new EncryptResponseBodyAdvice(); 
  14.     } 
  15.      
  16.     /** 
  17.      * 配置請(qǐng)求加密 
  18.      * @return 
  19.      */ 
  20.     @Bean 
  21.     public EncryptRequestBodyAdvice encryptRequestBodyAdvice() { 
  22.         return new EncryptRequestBodyAdvice(); 
  23.     } 
  24.      

 

責(zé)任編輯:武曉燕 來源: cxytiandi
相關(guān)推薦

2019-12-04 07:12:41

前端后端web安全

2020-02-13 09:52:48

加密前后端https

2011-03-31 09:40:46

2023-07-13 07:35:19

2012-05-10 09:50:53

云計(jì)算安全

2011-02-13 14:36:35

2013-02-18 16:12:55

2019-08-21 17:10:13

安全技術(shù)網(wǎng)絡(luò)安全網(wǎng)站

2022-06-22 09:00:00

安全編程語言工具

2018-10-23 14:24:10

2013-01-11 14:00:18

云存儲(chǔ)云計(jì)算云安全

2013-01-15 10:12:39

云存儲(chǔ)云安全

2010-05-17 16:26:36

IIS安全

2023-07-27 12:26:11

2021-05-26 08:49:15

API接口安全

2022-03-10 14:17:11

區(qū)塊鏈數(shù)據(jù)安全技術(shù)

2023-11-13 16:08:59

2021-05-20 11:20:52

數(shù)據(jù)隱私安全

2011-05-25 10:37:03

Oracle數(shù)據(jù)庫安全

2024-12-18 14:06:56

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)