認為實施隨機數很簡單?再想想。 無論你是在構建鏈上協議還是鏈下基礎設施,正確的隨機數實施都是加密安全中最棘手的部分之一。 讓我們深入探討為什麼重放保護比看起來更難 👇
2/ 首先,讓我們了解數位簽名。在公鑰加密(如 BLS)中,您擁有一個私鑰來簽署消息,還有一個公鑰來驗證它們。 在 Ethereum 中: 地址 = 公鑰哈希 消息 = 交易哈希 簽名 = 64 字節的加密證明
3/ 問題在於:大多數公鑰加密協議中的數學並不限制對同一消息驗證簽名的次數。一旦你擁有有效的簽名,你可以無限次重播它。這為重播攻擊打開了大門。
4/ 輸入隨機數:一個「只使用一次的數字」,用來防止重放攻擊。當消費者收到帶有隨機數的消息時,它會檢查該隨機數是否之前已被使用。如果是 → 拒絕。Ethereum 交易使用這種模式。
5/ 但隨機數的實現是欺騙性地複雜。關鍵要求: - 隨機數絕不能重複使用(在此鏈或其他鏈上) - 必須永久防止重放攻擊 - 需要機制來處理存儲增長 - 必須抵抗前置交易攻擊
6/ 天真的解決方案:將所有 nonce 永久存儲在數據庫中。這有兩個主要問題: a) 無界限的存儲增長(特別是在垃圾郵件攻擊的情況下) b) 易受前置交易攻擊的影響 問題 (a) 比 (b) 更容易解決。讓我們先處理存儲問題...
7/ 基於時間戳的隨機數解決了存儲增長問題!使用時間戳 + 到期時間。超過 5 分鐘的隨機數將從數據庫中刪除。但同一帳戶的同時消息怎麼辦?它們共享一個時間戳。解決方案:時間戳 + random_bytes 以實現更細粒度的唯一性。
8/ 前置交易是棘手的部分。惡意行為者可以攔截有效的簽名,然後前置交易將隨機數標記為已使用,這樣合法用戶的請求就會被拒絕。在鏈上,這在批量操作中是有問題的,如果一個錯誤的簽名拒絕了整個批次。對於鏈下:使用 TLS 加密!不要讓任何惡意行為者看到隨機數或簽名。
9/ 別忘了持續性!如果你的 nonce 快取僅在記憶體中,攻擊者可以在系統重啟後重放舊的 nonces。始終將 nonce 狀態持久化到耐用存儲中,並在啟動時重新加載。僅在記憶體中的快取 = 重放漏洞窗口。
10/ 每個消費者的唯一隨機數!在向多個用戶廣播時,每個用戶應該收到不同的消息/簽名。否則,您將面臨中間人攻擊的風險,攻擊者可能會轉發消息,冒充原始發件人。
11/ 增量非ces(像Ethereum,nonce = 前一個nonce + 1)有其存在的必要性,但要小心!它們為鏈下基礎設施帶來了巨大的挑戰:消息順序錯亂、同步問題和複雜的恢復場景。只有在你確信消息會(或必須)按順序到達時才使用。
摘要 - Nonce 實作檢查清單: ✅ 使用 nonces 來防止重放攻擊 ✅ 在重啟後持久化 nonce 狀態 ✅ 實作過期機制(時間戳 + 清理) ✅ 確保每個接收者的 nonces 唯一 ✅ 透過加密通道防止前置交易 ✅ 除非保證順序,否則避免增量 nonces 安全在於細節! 🛡️
4.06K