Hash

來自有限熵的連續強隨機性流?

  • January 2, 2016

我需要一個連續(無限)強隨機生成器,但我只有有限的熵作為種子。我知道那裡已經存在矛盾,但我正在尋找一種實用的方法。

假設我有一個 1024 位的強隨機熵(這個特定流的一個時間常數)和一個密碼安全的散列函式,比如 Sha512 或 Sha3-512。

這是否會生成適當的隨機數據流:

  • 下一個隨機位塊 = 散列(unix 或系統時間 || 熵 || 最後一個隨機位塊)

從根本上說,我知道其中沒有比最初的 1024 位更多的真正熵。再加上unix或系統時間每輪可能有一點點(如果我們需要幾微秒,可能會多一點),但這是非常可預測的。

然而考慮到雜湊是一個CSPRNG,我會說輸出將是完全不可預測的,並且對於所有合理的目的來說足夠好了嗎?還是我忽略了什麼?

例如,只要初始種子仍然隱藏,在使用這種隨機流提取加密密鑰時,這種“洩漏”或會帶來任何安全風險嗎?(應該是獨立的)

如評論中所述,只需使用您的初始熵來播種確定性隨機比特流生成器,例如NIST SP 800-90A Rev.1中指定的那些,或作為任何安全流密碼或OFB / CTR中的塊密碼的密鑰mode,應該足以生成幾乎與隨機無法區分的比特流。

實際上,1024 位的種子熵對於這個來說是多餘的。 即使是 256 位的密鑰空間也無法使用已知的物理學(是的,甚至是量子計算)和人類可用的資源來列舉,因此唯一的方法是打破(即在沒有密鑰的先驗知識的情況下區分真正的隨機性)具有 256 的 DRBG位種子長度是通過利用生成器中的某些缺陷的密碼分析攻擊來實現的——添加更多的種子熵通常無助於對抗此類攻擊。這是幸運的,因為大多數標準 DRBG / 密碼實際上並不接受長於 256 位的種子 / 密鑰,或者,如果他們接受,它們會在內部將其散列到更短的內部狀態。

也就是說,如果您選擇的 DRBG 不直接接受長密鑰,並且如果您不能100% 確定您的 1024 位種子確實具有 1024 位,您可能仍希望將其散列到 256 位(使用安全加密雜湊函式),而不是簡單地截斷它,然後再將其提供給 DRBG。或者,您可以簡單地使用基於散列的 DRBG(例如 SP 800-90A.1 中的 Hash_DRBG 或 HMAC_DRBG 結構,或SHA-3 / FIPS 202中的 SHAKE 函式),它直接接受任意長的種子,並自動散列它縮小到其內部狀態大小。


無論如何,如果沒有比系統時間更好的熵源,我不會費心嘗試將額外的熵合併到 PRNG 狀態中——或者至少,不是你建議的方式。具體來說,您提出的方法有幾個嚴重的弱點:

  • 如果初始熵被洩露,攻擊者只需觀察一個輸出塊並猜測下一個輸出何時生成,就可以相當容易地預測未來的輸出。(精確的難度級別將取決於時鐘輸入的精度,以及使用模式的可預測性,但即使在最好的情況下,也不太可能阻止嚴重的攻擊者。)
  • 特別是,通過觀察被一個未知塊分隔的兩個輸出塊,攻擊者既可以猜測中間塊*,*又可以非常有效地驗證他們的猜測(尤其是如果他們可以在短時間內觀察到這兩個塊)。
  • 相反,如果初始熵沒有洩漏,則在系統時間中混合併不能真正提供任何附加值。然而,它確實破壞了生成器的確定性,這可能被認為是一個缺點。
  • 此外,如果種子熵洩露,並且攻擊者可以觀察到生成器的兩個或多個先前生成的連續輸出,他們可能能夠了解這些輸出是何時生成的,這可能是人們可能不希望透露的資訊。

如果您確實希望從系統時間(或其他低密度熵源)中加入額外的熵,我建議使用適當的熵池設計,例如Fortuna,它旨在通過將熵累積到多個內部來從狀態妥協中恢復只有在積累了足夠的熵以抵抗蠻力猜測時才用於重新播種到 PRNG 的池。

CSPRNG 能夠從狀態妥協中恢復。您提出的方法不能。您設計的內部狀態包括 unix 或系統時間、1024 位熵和前一個隨機輸出塊。一旦這些值被洩露,攻擊者就可以暴力破解時間值來猜測後續的輸出塊。如果攻擊者可以從你的生成器請求隨機數,那麼事情就變得更容易了——他知道自己請求的時間,並且他擁有他請求的先前輸出塊。

您的設計的安全性也不可靠。具有熵源的 CSPRNG 的全部意義在於使它們能夠從狀態妥協中恢復。換句話說,如果我們確定 PRNG 的內部狀態永遠不會受到損害,那麼就沒有必要不斷地將新的熵混入其內部狀態。此外,我們需要盡可能多的熵源。這是因為我們想要盡可能多的熵(出於第 1 段中所述的原因),而且我們永遠無法確定攻擊者不會破壞源本身。在您的情況下,您只有 1 個熵源——unix 或系統時間。這當然是不夠的。

您的設計的另一個可能有問題的特徵(取決於應用程序)是您無法輕鬆複製隨機序列。給定特定種子時,PRNG 應該能夠重複相同的輸出。您在這裡所做的是在生成每個輸出塊之前重新播種。因此,您複製輸出序列的唯一方法是儲存所有時間值。這對於加密密鑰來說很好,但是如果您想使用相同的隨機參數集重複模擬,那麼您將遇到一些麻煩。

引用自:https://crypto.stackexchange.com/questions/30956