防重放攻擊實現


本文為博主原創,未經允許不得轉載

1.防重放攻擊:請求被攻擊者獲取,並重新發送給認證服務器,從而達到認證通過的目的。

2。解決方案:

 a. 基於timestamp防止重放攻擊

       每次 http 請求時,都添加 timestamp 時間戳的參數,服務端接收到請求時,解析 timestamp 值,並與當前時間進行比較,判斷是否超過60s,

  如果超過60s 則丟棄該請求。

 b. 基於nonce值得防重放攻擊

    每次http請求時,都添加 一個固定長度的隨機數或請求ip加隨機數進行hash生成的字符串,服務端在接受到請求的時候,解析請求的nonce值,並將nonce值存於數據庫或緩存中,

  當請求時,判斷數據庫或緩存中是否存在該nonce值,如果存在則丟棄該請求。 此時,使用nonce值,在 http 請求時,nonce值可以保證請求的唯一性。

 c .基於timstamp和nonce值防止重放攻擊

      單純基於 timestamp 進行防重放攻擊也會存在風險,如果請求被中間人或是黑客獲取,且請求的時間戳與當前時間比較時,仍小於60s 時,此時則

  不能進行防重放攻擊。

    單純使用nonce值時,需要服務端不斷地保存nonce值,則會導致數據庫保存大量的nonce值,影響效率。

    基於以上兩種情況,則將兩者結合一起使用,nonce值可以保證請求的唯一性,timestamp可以保證請求的時效性。並將保存於數據庫或緩存中的nonce值,

  每隔60s清除一次或將緩存中的nonce值時效時間設置為60s。這樣就可以減少nonce值對數據庫的壓力,提高性能。

 

3. 使用證書(公鑰與私鑰),timestamp 與nonce值進行防重放與防篡改  

  以上請求中nonce值或時間戳等值,若都使用明文傳輸,會存在被中間人或黑客截取,再次發起請求的風險。

  很多需要進行防重放攻擊的場景則都需要保證很高的安全性,所以在整個過程中,可以使用證書進行數據簽名,保證請求不被篡改。

  使用證書的公鑰與私鑰保證請求參數以及timestamp與nonce值不被篡改的方案有兩種:

    第一種方案:(客戶端使用公鑰對數據加密,服務端私鑰解密,校驗數據的有效性)

      1.客戶端向服務端發起https請求

      2.服務端接受到請求后,生成公鑰和私鑰,公鑰相當於鎖,私鑰相當於鑰匙,只有私鑰才能打開公鑰的內容

      3.服務端返回客戶端公鑰。

      4.客戶端接受到公鑰,並解析公鑰的有效性,比如頒發者,到期時間等,如果解析異常,則提示證書錯誤,並進行證書更新。

        客戶端解析公鑰ok后,對請求體進行加密(此時可將timestamp與nonce值在請求體中進行傳輸),並傳輸給服務端

      5.服務端解析客戶端傳過來的數據,並進行解析,並找到保存於服務端的私鑰,對該請求體進行解密,並解析出timestamp 與

        nonce值,此時判斷兩個值得有效性,如果在使用服務端私鑰進行解密處理異常時,則提示請求非法。

    

    第二種方案:(客戶端使用私鑰簽名,服務端使用公鑰驗簽,校驗數據的有效性)

      1.客戶端向服務端發起https請求

      2.服務端接受到請求后,生成公鑰和私鑰,公鑰相當於鎖,私鑰相當於鑰匙,只有私鑰才能打開公鑰的內容

      3.服務端返回客戶端私鑰

      4.客戶端使用私鑰對請求進行簽名(簽名的格式可以將HTTP請求頭與請求體按按照一定格式進行簽名:String signStr = header+&+body),

        並使用authorition 字段以請求頭的方式,將簽名的數據傳到服務端

      5.服務端解析對應的請求,解析出請求頭與請求body,拼接簽名的原始格式:String signStr = header+&+body,服務端並解析出該請求私鑰

        對應的公鑰。用公鑰驗簽,判斷數據是否被篡改,驗簽通過后,解析出nonce 值與timestamp值,進行防重放的校驗

  

  使用公鑰驗簽與私鑰解密的方式可以參考這篇文章:

      RSA 加密,解密,簽名,驗簽

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM