我應該在挑戰-響應工作量證明中使用什麼挑戰?
為了防止拒絕服務攻擊,我想要求客戶端在與他們交談之前做一些工作(比伺服器完成請求更多的工作)。
- 客戶端連接
- 伺服器發送一個挑戰,包括一條數據
“查找字節 x 使得 hash(challengeData + x) 在開頭有 n 個零” 3. 客戶端找到x,發送給伺服器 4. 伺服器驗證 hash(challengeData + recv()) 開頭有 n 個零 5. 實際請求被處理
我發現了幾種不同的方法來生成這個“challengeData”的東西,每個都有一些問題:
- 隨機字節
在這裡,客戶端可以通過重複連接來耗盡伺服器的 PRNG。這讓我們回到了第一方(拒絕服務)。
- 目前時間
這對我來說似乎是個好主意,但我想知道你可以對它進行哪些攻擊。
- 一個涉及依賴於這個特定請求的東西的字元串(比如hashcash)
為了確保盡快刪除惡意連接,我想在確保客戶端完成一些工作之前避免處理有關請求的任何內容。這個想法是客戶端在開始處理請求之前應該總是比伺服器做更多的工作。
我有一些限制:首先我希望伺服器完全無狀態。我不想保存“hashcash”並確保它不會被花費兩次,而是我想挑戰客戶做那些本質上不能預先計算的工作。其次,在這個階段我不想知道有關請求本身的任何資訊(例如身份驗證)。這樣伺服器就可以發送和接收盡可能少的數據。例如,目前時間(納秒或毫秒精度,取決於作業系統、硬體和實現)為 8 個字節(雙精度),之前 2^64-1 次嘗試(即 8 字節響應)應該綽綽有餘重置連接(在可預見的將來)。
簡而言之:
- 這個挑戰需要具備哪些屬性?
- 哪些易於生成的數據具有所有這些屬性?現在的時間好嗎?
像往常一樣,當我詢問有關協議設計的問題時,這很可能是在重新發明輪子。如果有任何現有的協議可以做到這一點,我還不知道它們。
一天中的使用時間是可預測的。挑戰對對手來說應該是不可預測的。如果不是(就像你說的那樣),對手可以提前解決一系列挑戰,然後快速連續使用它們來引發 DOS。您想要計量對服務的訪問,這不僅是為了確保客戶端做一些工作,而且這些工作是在他們想要連接的時候完成的。同樣,挑戰應該在一段時間後超時。
也就是說,可以將時間作為一個參數(以及任何其他連接細節)包含在建構挑戰中以確保答案是及時的。
我將通過將日期與隨機生成的隨機數組合(例如散列)來建構挑戰(PRNG 在宇宙的生命週期中不會重複)。如果您隨後使用您的密鑰 MAC 挑戰,您將不必記錄 nonce 的值。客戶端應返回日期、隨機數、挑戰、解決方案和 MAC。伺服器將驗證日期是否在有效時間段內,日期和隨機數生成挑戰(查找不同的日期和隨機數會減少在雜湊函式中發現衝突),挑戰上的 MAC 有效(使用您的密鑰) ,並且挑戰的解決方案是有效的。
在這種情況下,伺服器需要保留的唯一“狀態”是時鐘和密鑰,這是與連接數無關的恆定成本。但是,它確實增加了通信複雜性(發送到伺服器和從伺服器發送的組件數量)。
這是本文中無狀態協議的一個非常簡化的版本,您可以使用它來獲得更強的安全保證。
您也可以考慮使用與基於散列的拼圖不同的拼圖。基於散列的謎題很容易並行化。有些是基於模冪/重複平方的,它們本質上是順序的。有關更多資訊,請參閱這篇最近的論文和引用的相關工作。