Hash

使用散列函式作為 PRG 有什麼問題嗎?

  • November 7, 2021

我需要在 JavaScript 中創建加密安全的偽隨機性。然而,當我用Google搜尋 PRG 時,我發現的都是非常粗略的。

我的想法如下(虛擬碼):

seed = "0x1a29fd..." // long number I always get passed (impossible to guess but used in a different context as well)
hashedAndSaltedSeed = sha256sum("seed: " + seed)
purpose = "..." // my current function's name (no spaces)
usageIndex = 1; // will increment this each time

randomness = myPrg(hashedAndSaltedSeed, purpose, usageIndex)

function myPrg(hashedAndSaltedSeed, purpose, usageIndex, numberOfBytes) {
   if(numberOfBytes > 32) {
       fail()
   }

   input = purpose + " " + usageIndex + " " + hashedAndSaltedSeed
   return sha256sum(input).binary2hex().slice(0, 2*numberOfBytes).hex2binary()
}

我只需要少量的隨機性(一次最多 32 字節,很少幾次),所以速度差異無關緊要。但是這種方法還有什麼問題嗎?

我需要的隨機性不需要完全隨機分佈,但是當只給定而不是 nor 時,猜測產生的隨機性需要purposeusageIndex不可行seedhashedAndSaltedSeed

編輯:對不起,我忘了提到一個重要的要求。我確定在我寫它的某個時候它在我的問題中,但我似乎不小心刪除了那部分。當給定相同的種子時,我需要能夠重現相同的隨機性。這就是為什麼我不能只使用給我隨機性但不能讓我控制種子的東西。

這很好,儘管您應該避免這些與十六進制之間的轉換,這是不必要的,並且可能會引入側通道。

現在,由於您使用的是 JavaScript,您可以簡單地使用 WebCrypto API。特別是 crypto.GetRandomValues,它可以填充一個最多 65536 字節的數組。

如果您不使用散列函式,而是使用分組密碼,這將精確地使用 CTR 模式作為 PRNG。這絕對可行,但我建議您閱讀這篇文章以查看一些您需要注意的實現細節(對於使用分組密碼/AES 的情況)。

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