APP之防重放攻擊

HTTPS數據加密是否可以防止重放攻擊?

否,加密可以有效防止明文數據被監聽,但是卻防止不了重放攻擊。

防重放機制

我們在設計接口的時候,最怕一個接口被用戶截取用於重放攻擊。重放攻擊是什麼呢?就是把你的請求原封不動地再發送一次,兩次...n次,一般正常的請求都會通過驗證進入到正常邏輯中,如果這個正常邏輯是插入數據庫操作,那麼一旦插入數據庫的語句寫的不好,就有可能出現多條重複的數據。一旦是比較慢的查詢操作,就可能導致數據庫堵住等情況,如果是付款接口,或者購買接口就會造成損失,因此需要採用防重放的機制來做請求驗證。

timestamp+nonce

我們常用的防止重放的機制是使用timestamp和nonce來做的重放機制。
timestamp用來表示請求的當前時間戳,這個時間戳當然要和服務器時間戳進行校正過的。我們預期正常請求帶的timestamp參數會是不同的(預期是正常的人每秒至多隻會做一個操作)。每個請求帶的時間戳不能和當前時間超過一定規定的時間。比如60s。這樣,這個請求即使被截取了,你也只能在60s內進行重放攻擊。過期失效。
但是這樣也是不夠的,還有給攻擊者60s的時間。所以我們就需要使用一個nonce,隨機數。
nonce是由客戶端根據足夠隨機的情況生成的,比如 md5(timestamp+rand(0, 1000)); 也可以使用UUID, 它就有一個要求,正常情況下,在短時間內(比如60s)連續生成兩個相同nonce的情況幾乎爲0。

服務端

服務端第一次在接收到這個nonce的時候做下面行爲:

  1. 
去redis中查找是否有key爲nonce:{nonce}的string

  2. 如果沒有,則創建這個key,把這個key失效的時間和驗證timestamp失效的時間一致,比如是60s。

  3. 如果有,說明這個key在60s內已經被使用了,那麼這個請求就可以判斷爲重放請求。

示例:
http://a.com/?uid=123&timestamp=1480556543&nonce=43f34f33&sign=80b886d71449cb33355d017893720666
這個請求中,uid是我們真正需要傳遞的有實際意義的參數,timestamp、nonce、sign都是爲了簽名和防重放使用。
timestamp是發送接口的時間,nonce是隨機串,sign是對uid、timestamp、nonce(對於一些rest風格的api,我建議也把url放入sign簽名)。簽名的方法可以是md5({祕要}key1=val1&key2=val2&key3=val3...)

服務端接到這個請求:

  1. 先驗證sign簽名是否合理,證明請求參數沒有被中途篡改

  2. 再驗證timestamp是否過期,證明請求是在最近60s被髮出的

  3. 最後驗證nonce是否已經有了,證明這個請求不是60s內的重放請求

web層面也可以採用在頁面中加入token方式、手機驗證碼、滑動驗證碼等方式來防止攻擊。

 

 

本文參考:https://segmentfault.com/a/1190000014821815 有刪改

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章