前後端交互如何保證安全性?

前言

前後端交互如何保證安全性?


前後端交互如何保證安全性?


web與後端,andorid與後端,ios與後端,像這種類型的交互其實就屬於典型的前端與後端進行交互。在與B端用戶進行交互的過程中,我們通常忽略了其安全性(甚至從未考慮安全性)。比如,請求和響應數據的明文傳輸,對接口並沒有做嚴格的身份校驗。如果我們還是按照這種思路去做C端用戶的交互,那麼等待著必將是血淋淋的教訓。接下來,我帶領大家如何在與C端用戶安全的進行交互。

保證安全性的幾種方式

前後端安全性的交互,大致可以分成如下幾類:

1、通信請求使用https

2、對請求參數進行簽名,防止數據被踹改

3、對請求參數以及響應進行加密解密處理

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

使用https

谷歌 Chrome 在18年七月份已經將所有的 HTTP 網站標記為“不安全”。並且已經有越來越多的第三方服務開始推薦甚至是強制要求使用 HTTPS 連接方式,比如現在用得特別多的微信登錄、微信支付、短信驗證碼、地圖 API 等等,又比如蘋果公司 2016 年在 WWDC 上宣稱,公司希望官方應用商店中的所有 iOS App 都使用安全的 HTTPS 鏈接與服務器進行通信。

那為什麼越來越多的 HTTP 都在逐漸 HTTPS 化?HTTP 協議(超文本傳輸協議)是客戶端瀏覽器或其他程序與 Web 服務器之間的應用層通信協議;HTTPS 協議可以理解為 HTTP+SSL/TLS, 即 HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL,用於安全的 HTTP 數據傳輸,http與https的區別如下圖所示:

前後端交互如何保證安全性?


不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文傳播,帶來了三大風險。

  • 竊聽風險(eavesdropping):第三方可以獲知通信內容。
  • 篡改風險(tampering):第三方可以修改通信內容。
  • 冒充風險(pretending):第三方可以冒充他人身份參與通信。

SSL/TLS協議是為了解決這三大風險而設計的,希望達到:

  • 所有信息都是加密傳播,第三方無法竊聽。
  • 具有校驗機制,一旦被篡改,通信雙方會立刻發現。
  • 配備身份證書,防止身份被冒充。

因此強烈建議,為了你的系統安全性,趕快切到https中去吧。

對請求進行簽名

我們先來看一個例子,假設用戶在下完單之後,可以更改訂單的狀態,用戶對後端發起請求 /user?orderId=123, 假設後端剛好也沒有對這筆訂單的身份進行驗證,那麼後果就是,我們根據orderId, 將這筆訂單的狀態進行了修改:

前後端交互如何保證安全性?


前後端交互如何保證安全性?


如果這時候,嘗試著將請求中的orderId 換成另外一個orderId, 也會同樣對這筆訂單做了修改,從安全角度來說這是我們不希望看到的,當然我們也可以加一下身份校驗,判斷該筆訂單是否屬於當前的用戶;除此之外,我們還應該對請求參數做一次簽名處理。

加簽和驗籤就是在請求發送方將請求參數通過加密算法生成一個sign值,放到請求參數裡;請求接收方收到請求後,使用同樣的方式對請求參數也進行加密得到一個sign值,只要兩個sign值相同,就說明參數沒有被篡改。

簽名參數sign生成的方法

  1. 將所有以頭參數(注意時所有參數),出去sign本身,以及值是空的參數,按參數鍵字母升序排序。
  2. 然後把排序後的參數按參數1值1參數2值2......參數n值n(這裡的參數和值必須是傳輸參數的原始值,不能是經過處理的,如不能將"轉成"後再拼接)的方式拼接成一個字符串。
  3. 把分配給接入方的驗證密鑰key拼接在第2步得到的字符串前面。
  4. 在上一步得到的字符串前面加上密鑰key(這裡的密鑰key是接口提供方分配給接口接入方的),然後計算md5值,得到32位字符串,然後轉成大寫,得到的字符串作為sign的值放到請求參數裡。

舉例

現在假設需要傳輸的數據:/guest/rechargeNotify?p2=v2&p1=v1&method=cancel&p3=&pn=vn(實際情況最好是通過post方式發送)

  1. 拼接字符串,首先去除值是空的參數p3,剩下p2=v2&p1=v1&method=cancel&pn=vn,然後按參數名字符升序排序得到字符串:method=cancel&p1=v1&p2=v2&pn=vn。
  2. 然後做參數名和值的拼接,最後得到methodcancelp1v1p2v2pnvn。
  3. 在上面拼接得到的字符串前面加上驗證密鑰key,假設是abc,得到新的字符串abcmethodcancelp1v1p2v2pnvn。
  4. 將上面得到的字符串進行md5計算,假設得到的是abcdef,然後轉為大寫,得到ABCDEF這個值即為sign簽名值。最終產生的url應該如下:/guest/rechargeNotify?p2=v2&p1=v1&method=cancel&p3=&pn=vn&sign=ABCDEF
  5. 注意:計算md5之前請確保請求發送方和接收方使用的字符串編碼一致,比如統一使用utf-8編碼,如果編碼方式不一致則計算出來的簽名會校驗失敗。

驗簽過程

其實就是將請求url按照上述的規則進行同樣的操作,計算得到參數的簽名值,然後和參數中傳遞的sign值進行對比,如果一致則校驗通過,否則校驗不通過。

對請求和響應進行加解密

可能有人會問,都使用了https了,為什麼還要對請求和響應再做一次加解密,因為有些第三方抓包工具,例如Charles 通過某些手段是可以抓取https的明文的,因此對一些敏感數據,我們需要進行加密處理,常見的加解密方式有AES 對成加密方式和RSA非對成方式,至於如何運用,可以參考https的原理,有點複雜,不過可以簡單分成如下幾步:

前後端交互如何保證安全性?


前後端交互如何保證安全性?


1.服務器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,服務器端保存著私鑰,不能將其洩露,公鑰可以發送給任何人。

2.服務器將自己的公鑰發送給客戶端。

3.客戶端收到服務器端的公鑰之後,會對公鑰進行檢查,驗證其合法性,如果發現發現公鑰有問題,那麼HTTPS傳輸就無法繼續。嚴格的說,這裡應該是驗證服務器發送的數字證書的合法性,關於客戶端如何驗證數字證書的合法性,下文會進行說明。如果公鑰合格,那麼客戶端會生成一個隨機值,這個隨機值就是用於進行對稱加密的密鑰,我們將該密鑰稱之為client key,即客戶端密鑰,這樣在概念上和服務器端的密鑰容易進行區分。然後用服務器的公鑰對客戶端密鑰進行非對稱加密,這樣客戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束。

4.客戶端會發起HTTPS中的第二個HTTP請求,將加密之後的客戶端密鑰發送給服務器。

5.服務器接收到客戶端發來的密文之後,會用自己的私鑰對其進行非對稱解密,解密之後的明文就是客戶端密鑰,然後用客戶端密鑰對數據進行對稱加密,這樣數據就變成了密文。

6.然後服務器將加密後的密文發送給客戶端。

7.客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,得到服務器發送的數據。

總結

前後端的交互如果做到以上使用https,對請求加解密以及對請求參數進行驗籤,基本上能解決大部分問題,但除此之外我們還應該做到對每個接口進行身份校驗,確保該接口只能由特定的用戶訪問,或者該筆數據只能由特定的用戶去進行修改。

"


分享到:


相關文章: