HTTP請求通過添加時間戳(timestamp)和隨機碼(nonce)簡單解決安全傳輸問題


    如今的互聯網,明文傳輸數據已是相當危險,寒假長達半年期間在家也簡單寫出了http加密傳輸數據以及如何避免重放攻擊(Replay-Attack)。

    進入正題,博主用到的后端Java框架SpringBoot,高速緩存Redis;前端js安全庫crypto-js、jsencrypt。

常見加密方式:

 1.對稱加密 對稱密鑰加密,又稱私鑰加密,即信息的發送方和接收方用一個密鑰去加密和解密數據。它的最大優勢是加解密速度快, 適合於對大數據量進行加密,但密鑰管理困難。常見對稱加密工具有AES、DES。

 2.非對稱加密 非對稱密鑰加密,又稱公鑰密鑰加密。它需要使用一對密鑰來分別完成加密和解密操作,一個公開發布,一個私有儲存。公鑰加密的數據只有唯一的私鑰解密,缺點是對大數據量加密很慢,可能影響性能。常見非對稱加密工具有RSA、DSA。

 3. 散列校驗 散列校驗又稱簽名,散列屬於不可逆加密,對不同的數據加密的結果是定長的,對原數據進行任何改動所得到的散列值都有很大區別,但對相同的數據加密,得到的結果相同。常見散列工具有MD5、SHA1、SHA256。

執行流程:

 登錄

  1. 前端在輸入密碼時向后端發送請求 (焦點事件)。

  2. 后端隨機生成nonce、當前timestamp以及前后端協商的salt(鹽),通過nonce+timestamp+salt隨機組合散列生成定長字符串作為sign一並返回前端。

  3. 后端保存request的sessionId和nonce到Redis中,取出nonce需要相同的sessionId。

  4. 前端進行timestamp超時檢查 ( 安全情況下,超時范圍在5秒以內,超過5秒則認為此nonce不安全 )。

  5. 前端用后端同樣方法生成sign並比對請求的sign是否完全相同,若不相同則認為此nonce被篡改。

  6. 點擊登錄發送賬號 (username)、當前時間戳 (timestamp) 和 Token [ SHA256( 賬號+SHA256(密碼)+時間戳+nonce ) ]。

  7. 后端判斷當前時間與請求中時間戳間隔 ( 正常情況下,客戶端請求最多為1分鍾,若超過1分鍾則認為請求已過期 ) 。

  8. 檢查Redis中Token與timestamp是否存在 ( 判斷方式:先檢查Token是否存在,若存在則檢查timestamp是否相同 ),存在表示這是一個重復請求。

  9. 若不存在則將Token與timestamp儲存到Redis中 (儲存方式 => key: token | value: timestamp),設置過期時間為前端請求有效時間。

  10. 后端通過賬號(username)前往數據庫獲取用戶數據,再通過SHA256( username+數據庫SHA256密碼+請求的timestamp+本地nonce )生成token。

  11. 若token與請求token不匹配則返回用戶名密碼錯誤,反之寫入Session並返回登錄成功。

 注冊

  1. 注冊唯一區別就是后端也要拿到密碼,同樣的輸入密碼時向后端發送請求。

  2. 后端生成RSA密鑰將私鑰與sessionId儲存到Redis中,同理取出私鑰需要相同的sessionId。

  3. 公鑰用[發送nonce相同的方法]發送pubkey、timestamp、sign。

  4. 前端同登錄做超時( timestamp )和簽名( sign )檢查。

  5. 前端使用散列 ( 隨機數+時間戳+固定salt ) 取隨機位數生成16位AesKey。

  6. 點擊發送時發送用戶名(username),密碼 [ AES( password ) ] ,當前timestamp,skey [ RSA( AesKey ) ] 和 sign [ RSA( SHA256( username+password+timstamp ) ) ]。

  7. 后端通過sessionId取得RSA私鑰解密skey、sign,再用AesKey解密password。

  8. 使用登錄相同的方式檢查當前請求是否過期(timestamp)。

  8. 使用前端相同方式生成簽名[ SHA256( username+password+timstamp ) ]與解密的sign做比對 ( 期間任何解密或校驗失敗都認為本次請求已被篡改 )。

  9. 檢查sign是否在Redis中且timestamp是否相同,若相同則認為這是重復請求,不相同則同登錄相同方式存入Redis中。

  10. 后端通過username判斷用戶是否已注冊,未注冊則寫入數據庫 (密碼推薦使用SHA256儲存) 並返回注冊成功。

  * 注冊的加密傳輸方式可適用於大的數據加密,因為RSA始終加密AES秘鑰,不會影響性能。js的salt長度不限但在前端是明文顯示,可以使用js加密加大破解難度,推薦sojsonv6,免費好用。

  如果有任何漏洞歡迎指出 ~


免責聲明!

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



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