溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

前后端API交互是怎么保證數(shù)據(jù)安全性

發(fā)布時間:2022-01-19 11:46:16 來源:億速云 閱讀:126 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)前后端API交互是怎么保證數(shù)據(jù)安全性,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

前言

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

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

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

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

  1. 通信使用https

  2. 請求簽名,防止參數(shù)被篡改

  3. 身份確認機制,每次請求都要驗證是否合法

  4. APP中使用ssl pinning防止抓包操作

  5. 對所有請求和響應(yīng)都進行加解密操作

  6. 等等方案…….

對所有請求和響應(yīng)都進行加解密操作

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

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

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

https://github.com/yinjihuan/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:是否開啟調(diào)試模式,默認為false,如果為true則不啟用加解密操作

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

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

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

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

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

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

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

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

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

  1. 統(tǒng)一處理數(shù)據(jù)的響應(yīng),在渲染到頁面之前進行解密操作

  2. 當(dāng)有POST請求的數(shù)據(jù)發(fā)出時,統(tǒng)一加密

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

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

首先還是要封裝一個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攔截器中統(tǒng)一處理代碼:

// 添加請求攔截器
axios.interceptors.request.use(function (config) {
   // 對所有POST請加密,必須是json數(shù)據(jù)提交,不支持表單
   if (config.method == "post") {
       config.data = EncryptData(JSON.stringify(config.data));
   }
   return config;
 }, function (error) {
   return Promise.reject(error);
});
// 添加響應(yīng)攔截器
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不泄露,別人得到你的數(shù)據(jù)也沒用,問題是如何保證key不泄露呢?

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

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

加密算法有對稱加密和非對稱加密,AES是對稱加密,RSA是非對稱加密。之所以用AES加密數(shù)據(jù)是因為效率高,RSA運行速度慢,可以用于簽名操作。

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

其實大家理解了HTTPS的原理的話對于下面的內(nèi)容應(yīng)該是一看就懂的,HTTPS比HTTP慢的原因都是因為需要讓客戶端與服務(wù)器端安全地協(xié)商出一個對稱加密算法。剩下的就是通信時雙方使用這個對稱加密算法進行加密解密。

  1. 客戶端啟動,發(fā)送請求到服務(wù)端,服務(wù)端用RSA算法生成一對公鑰和私鑰,我們簡稱為pubkey1,prikey1,將公鑰pubkey1返回給客戶端。

  2. 客戶端拿到服務(wù)端返回的公鑰pubkey1后,自己用RSA算法生成一對公鑰和私鑰,我們簡稱為pubkey2,prikey2,并將公鑰pubkey2通過公鑰pubkey1加密,加密之后傳輸給服務(wù)端。

  3. 此時服務(wù)端收到客戶端傳輸?shù)拿芪模盟借€prikey1進行解密,因為數(shù)據(jù)是用公鑰pubkey1加密的,通過解密就可以得到客戶端生成的公鑰pubkey2

  4. 然后自己在生成對稱加密,也就是我們的AES,其實也就是相對于我們配置中的那個16的長度的加密key,生成了這個key之后我們就用公鑰pubkey2進行加密,返回給客戶端,因為只有客戶端有pubkey2對應(yīng)的私鑰prikey2,只有客戶端才能解密,客戶端得到數(shù)據(jù)之后,用prikey2進行解密操作,得到AES的加密key,最后就用加密key進行數(shù)據(jù)傳輸?shù)募用?,至此整個流程結(jié)束。

spring-boot-starter-encrypt原理

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

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

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

EncryptAutoConfiguration中配置請求和響應(yīng)的處理類,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中對請求進行統(tǒng)計處理比較方便。如果還要更底層去封裝那就要從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就可以對請求響應(yīng)做處理了,大概的原理就是這么多了。

上述就是小編為大家分享的前后端API交互是怎么保證數(shù)據(jù)安全性了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

api
AI