BouncyCastle 風格的 ThreadedSeedGenerator
我編寫了一個 BouncyCastle 風格的執行緒播種器,並且想知道程序生成的數據的可預測性。
我不簡單地使用 BouncyCastle 的原因是安全性不是問題,我不想只為一個函式使用整個庫,而且這段程式碼要快得多。
這個想法是讓幾個執行緒在循環緩衝區(一個簡單的數組)上執行,其中每個執行緒對緩衝區中的數據執行不同的操作。隨機性來自作業系統中的執行緒調度不規則性。
我可以從這樣的機制中獲得多少隨機性?
C#程式碼:
using System; using System.Threading; class ThreadedSeeder { static public ulong[] buffer = new ulong[1024]; static public bool doThread = true; public ThreadedSeeder() { MakeThread(Add); MakeThread(Multiply); MakeThread(Xorshift); Thread.Sleep(10); doThread = false; } static private void MakeThread(ThreadStart a) { Thread b = new Thread(a) { Priority = ThreadPriority.Lowest }; b.Start(); } static private void Add() { int i = 0; while (doThread) { buffer[i & 1023] += (ulong)DateTime.UtcNow.Ticks; i++; } } static private void Multiply() { int i = 0; while (doThread) { buffer[i & 1023] *= 6364136223846793005; i++; } } static private void Xorshift() { int i = 0; while (doThread) { ulong y = buffer[i & 1023]; y ^= (y << 13); y ^= (y >> 17); y ^= (y << 5); buffer[i & 1023] = y; i++; } } }
這種方法在許多方面都存在嚴重缺陷。
- 在重負載下,整體返回為零是非常合理的
buffer
,這是攻擊者經常可以故意造成的(例如,需要高 CPU 負載的網路流量氾濫;會想到啟動多個 https 連接)。這很可能是一場實際的災難。機制:啟動的三個執行緒
ThreadedSeeder
都設置為Lowest
-priority,所以在Thread.Sleep(10)
.Lowest
如果機器在暫停期間的優先級高於執行的操作,則可以在執行緒測試doThread = false
之前繼續執行,因此不執行與 相關的任何操作。這同樣適用於和Add``doThread``Add``buffer``Multiply``Shift``buffer
也是,但這無關緊要,因為這些執行緒即使執行也不能歸零。 2.DateTime.UtcNow.Ticks
更一般地說,呼叫次數幾乎沒有保險;這可能很少,包括每個buffer
條目少於一次,因此所有其他條目總是為零。機器越忙,一個buffer
條目就越有可能沒有、一個或很少的讀數DateTime.UtcNow.Ticks
影響它。 3. 我沒有看到任何機制阻止Multiply
或Xorshift
競爭它的操作Add
元素,buffer
因此Add
同時進行的更改無效。這是一種不受控制的競爭條件,它可能會失去一些收集到的熵。 4.DateTime.UtcNow.Ticks
可以被對手非常接近。那應該是UTC時間,這不是秘密。此外,諸如RFC 7323高解析度 TCP 時間戳之類的常見機制允許找到特定機器認為的 UTC 時間,即使它的同步性很差。當機器處於輕負載狀態時,一個 CPU 執行每個執行緒,包括Add
全速執行,讀數之間的差異將是可重複的。 5. 從DateTime.UtcNow.Ticks
緩衝區到每個元素中的內容的轉換是相對較少的公共轉換之一。並且這些可能的轉換中的每一個都是可逆的(通過奇數常數模乘以 2 的冪的模乘是可逆的Multiply
,以及 中的三個按位運算中的每一個都是可逆的Xorshift
)。結合 4,buffer
只要只有一個DateTime.UtcNow.Ticks
影響它的元素輸出,它就可以輕鬆地在每個元素輸出上使用一個非常有選擇性的區分器,還可以揭示發生了哪個轉換。看起來這可以擴展到一些這樣的影響。 6. 程式碼和問題的文本都沒有顯示任何努力創建收集的熵的顯式擴散:元素buffer
永遠不會混合。如果在使用前沒有這種混合或/和後處理,2/4/5 的buffer
某種程度可能是一場實際的災難。 7. 定時執行不會在某些精確控制的執行環境中收集任何熵,包括硬體工程師使用的虛擬機/模擬器或惡意軟體的逆向工程。最終,buffer
輸出的狀態,以及由此確定的任何東西,將僅取決於任務何時啟動。