第一種方法:
重放攻擊是計算機世界黑客常用的攻擊方式之一,所謂重放攻擊就是攻擊者發送一個目的主機已接收過的包,來達到欺騙系統的目的,主要用於身份認證過程。
首先要明確一個事情,重放攻擊是二次請求,黑客通過抓包獲取到了請求的HTTP報文,然後黑客自己編寫了一個類似的HTTP請求,發送給伺服器。也就是說伺服器處理了兩個請求,先處理了正常的HTTP請求,然後又處理了黑客發送的篡改過的HTTP請求。每次HTTP請求,都需要加上timestamp參數,然後把timestamp和其他參數一起進行數字籤名。因為一次正常的HTTP請求,從發出到達伺服器一般都不會超過60s,所以伺服器收到HTTP請求之後,首先判斷時間戳參數與當前時間相比較,是否超過了60s,如果超過了則認為是非法的請求。假如黑客通過抓包得到了我們前臺的請求url:網址?uid=110&stime=1520862753&sign=80b886d71449cb33355d017893720666 其中$sign=md5($uid.$token.$stime); // 伺服器通過uid從資料庫中可讀出token後端開始解析,一般情況下,黑客從抓包重放請求耗時遠遠超過了60s,所以此時請求中的stime參數已經失效了。 如果黑客修改stime參數為當前的時間戳,則sign參數對應的數字籤名就會失效,因為黑客不知道token值,沒有辦法生成新的數字籤名。
1、先判斷stime 與當前伺服器時間差值是否大於60s如果大於那麼可以拒絕響應該請求
2、驗證$sign 根據約定的規則判斷後端生成的sign與前臺傳過來的sign是否一致
3、如果驗證通過則根據uid查詢用戶信息
但這種方式的漏洞也是存在的,如果在60s之內進行重放攻擊,那就沒辦法了,所以這種方式不能完全保證請求僅一次有效。
第二種方法:
我們在timestamp方案的基礎上,加上隨機字符串nonce參數,因為timstamp參數對於超過60s的請求,都認為非法請求,所以我們只需要在服務端存儲60s的nonce參數的「集合」即可。假如黑客通過抓包得到了我們的請求url:網址?uid=110&stime=1520862753&sign=80b886d71449cb33355d017893720666&nonce=HNJDHJNHHJ323其中$sign=md5($uid.$token.$stime.$nonce); // 伺服器通過uid從資料庫中可讀出token如果在60s內,重放該HTTP請求,因為nonce參數已經在首次請求的時候被記錄在伺服器的nonce參數「集合」中,所以會被判斷為非法請求。超過60s之後,stime參數就會失效,此時因為黑客不清楚token的值,所以無法重新生成籤名。
綜上,我們認為一次正常的HTTP請求發送不會超過60s,在60s之內的重放攻擊可以由nonce參數保證,超過60s的重放攻擊可以由stime參數保證。因為nonce參數只會在60s之內起作用,所以只需要保存60s之內的nonce參數即可我們並不一定要每個60s去清理該nonce參數的集合,只需要在新的nonce到來時,判斷nonce集合最後一次修改時間,超過60s的話,就清空該集合,存放新的nonce參數集合。其實nonce參數集合可以存放的時間更久一些,但是最少是60s。隨機數集合可以根據業務場景採用定期清理或根據大小自動清理的方案,例如該接口每秒的請求數最高為1000,則60s內的請求數量最多為1500*60=90000,則我們在每次請求後檢查集合大小是否超過90000,若超高該數量則清空。