Hash

使用 SHA512 生成一個數字,使用者可以稍後驗證(一旦我發布秘密種子)

  • May 6, 2022

我編寫了以下 C# 方法,該方法基本上需要 3 個種子,並為您提供 0-100 範圍內的數字。然後我將這個數字用於各種目的,但對於這個問題,最重要的一個是客戶端查看伺服器並提供客戶端價值的能力。這是方法:

// random sha512
private const decimal DIVIDER = (uint.MaxValue - 1)/100M;
public static decimal Random0To100(string secret, string server, string client)
{
   // add 3 strings together, calculate SHA512 hash
   var str = secret + server + client;
   var byt = Encoding.ASCII.GetBytes(str);
   byte[] hashByte = null;
   using (SHA512 shaM = new SHA512Managed())
   {
       hashByte = shaM.ComputeHash(byt);
   }

   // convert hash into hexadecimal string
   var hexHash = BitConverter.ToString(hashByte).Replace("-", "");

   // get unsigned 32 integer from first 8 chars of hash
   var hex8 = hexHash.Substring(0, 8);
   uint l = Convert.ToUInt32(hex8, 16);

   // get number between 0 and 100 from hash with 2 decimals
   var num = l / DIVIDER;
   var fin = Math.Round(num, 2);

   // return result, like 71.28
   return fin;
}

秘密種子是作為字元串發送的 512 位值。

我很好奇的是,如果最終使用者能夠長時間提供伺服器和客戶端值(並明顯看到 0-100 輸出),最終使用者是否有可能猜測秘密種子(比如時間是24 小時,我施加的唯一限制是這些伺服器/客戶端在添加在一起時至少有 10 個字元長)。

如果您認為理論上可以猜測秘密,請告知我可以在不過多更改算法的情況下做什麼。我在想各種各樣的事情:

  1. 增加種子大小(1024、2048…等)
  2. 將範圍從 uint (32bit) 增加到 ulong (64bit)
  3. 對伺服器/客戶端字元串實施更嚴格的要求

基本上,我只是想確保某人不可能猜測種子或隨機數,同時仍然為使用者提供提供伺服器和客戶端值的能力(顯然對於伺服器值,我將根據使用者請求在伺服器上重新生成它,不允許他直接提供)。

由於大量評論(其中大部分指向不相關的事情),讓我嘗試澄清這個問題。簡而言之,我想做的是生成一個隨機數,使用者以後可以驗證它沒有被我以任何方式固定/影響。因此,我將使用 RNGCryptoServiceProvider 生成秘密種子,長度為 512 個字元。然後我將賦予客戶端生成 10 個抽獎號碼的能力(他們可以為他們發送的每個請求請求生成新的伺服器種子,並發送任意字元串作為客戶端種子)。在這 10 個數字之後,我將生成新的秘密種子,發布舊的,這樣他們就不會看到任何受我影響的東西等等……

我也是:

  • 不嘗試發明新的加密標準
  • 不嘗試生成真正的隨機數

我正在建構一個接收字元串(秘密+伺服器+客戶端種子)並產生從 0.00 到 100.00 的數字的方法。我唯一想知道的是,如果他能夠從該方法中獲得足夠的數字(+ 他看到伺服器字元串並且可以發送任意客戶端字元串),他是否可以猜測秘密字元串。就這樣。沒有自製加密貨幣。沒有真正的隨機。

因此,如果任何具有電腦科學知識的人都可以確認我在算法中所做的事情不容易受到攻擊(使用者可以在發送伺服器/客戶端種子並取回幾個值後猜測秘密種子),或者提出更好的方法並發布程式碼解釋它-我將非常感激。否則,如果您只能談論理論並發布不相關的連結,我懇求您別管這個問題,不要污染它。謝謝。

為了在實踐中顯示,這些是 5 個隨機數以及伺服器/客戶端種子(伺服器 = 伺服器種子,c = 客戶端種子,數字 = 從該方法生成的數字;伺服器和客戶端種子故意縮短)。

如果你能猜出秘密種子,請告訴我。如果您需要更多的計算能力,請將您嘗試執行的算法發送給我,我將對其進行審查並將其放在多台伺服器上執行。

通過您的澄清編輯,您可以清楚地看到您在尋找什麼。

Generated Value = SHA512(A || B || C)
Where A = 512 bit secret
Where B = x bits server seed and can be attacker chosen
Where C = x bits client seed and can be attacker chosen

我很好奇的是,如果最終使用者能夠長時間提供伺服器和客戶端值(並明顯看到 0-100 輸出),最終使用者是否有可能猜測秘密種子(比如時間是24 小時,我施加的唯一限制是這些伺服器/客戶端在添加在一起時至少有 10 個字元長)。

如果您使用的是 SHA-512,並且您使用的是具有至少一半熵的 512 位秘密,那麼不,他們應該不可能確定秘密種子。這是對 512 位未知輸入的 512 位雜湊函式的蠻力攻擊,目前這個星球上不存在在 24 小時(或 24 年)內完成此操作的計算能力。你應該能夠用這個秘密產生數十億的輸出並保持安全。

同樣的邏輯也可以在沒有秘密的情況下猜測輸出。儘管您的輸出大小是一個問題,但如果攻擊者控制伺服器和客戶端種子但不知道秘密,則無法預測雜湊的輸出。

我還建議您為任何給定的伺服器提前生成所有可能的客戶端種子的輸出列表,以使客戶感到舒適。這意味著擁有更大的伺服器和客戶端種子,我會說長度為 64 到 128 位。

您的伺服器種子應以全熵固定且永不更改,讓它們成為該伺服器的唯一 ID。作為客戶,我會更自在,知道您不是故意操縱它們以以某種方式匹配秘密。它們可以確定地生成,例如通過在計數器模式下使用分組密碼並遞增計數器。發布用於生成它們的密鑰(例如 SHA256(“生成密鑰”))和使用的方法是一個好主意,證明它們沒有特殊的生成方式。

客戶端種子也應該足夠大,以至於不太可能發生衝突。我建議為每個客戶端發布一個 64 位使用者 ID,並允許客戶端為其輸入選擇第二個 64 位值,並將它們連接起來形成客戶端種子。

這為雜湊提供了 3 個輸入,一個 512 位機密,一個 128 位伺服器種子和一個 128 位客戶端種子。所有 3 個都經過雜湊的單次迭代,然後被壓縮或截斷。如果我是客戶,並且知道該計劃是如何運作的,我相信你無法操縱結果,即使你從未公佈過秘密。發布秘密將使我能夠驗證您是否確實按照您描述的方式使用該方案。

當然,我需要知道您在第一次客戶端輸入後沒有操縱秘密,這可以通過發布一些東西來證明您使用的是什麼秘密但不允許知道秘密,例如 SHA256(SHA256(Secret )) 比特幣工作量證明。在輸入客戶端種子之前發布它是微不足道的,然後一旦發布秘密,使用者可以在處理第一個客戶端種子之前驗證秘密存在。

我在這裡擔心的是你的輸出的大小。十進制數似乎….很小。我建議使用 32 位或 64 位無符號整數值,例如轉換為十六進制的前幾個雜湊字節。如果你有一些特定的原因讓十進制輸出只有 10000 個可能的輸出,我想听聽。這會讓我作為客戶感到不舒服,除非有很好的理由。

一位斯蒂芬說,您應該維護所有生成值的可驗證記錄。

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