應用“PushEntropy”功能會增加私鑰的安全性嗎?
我只是在查看NBitcoin-package的原始碼。據我所知,當您創建新的比特幣密鑰對時
Key privateKey = new Key();
(不傳遞一些隨機數據用作您自己生成的私鑰)然後庫使用隨機數生成器為您生成一個私鑰。很平常。但後來我偶然發現了隨機數生成器的輸出不會直接用作私鑰的事實:NBitcoin 還在這個字節數組上應用了PushEntropy函式:
private static void PushEntropy(byte[] data) { if (!UseAdditionalEntropy || additionalEntropy == null || data.Length == 0) return; int pos = entropyIndex; var entropy = additionalEntropy; for (int i = 0; i < data.Length; i++) { data[i] ^= entropy[pos % 32]; pos++; } entropy = Hashes.SHA256(data); for (int i = 0; i < data.Length; i++) { data[i] ^= entropy[pos % 32]; pos++; } entropyIndex = pos % 32; }
我理解這個函式的作用,但我不明白為什麼我們需要這個函式來生成一個私鑰。
為什麼加密安全的隨機數生成器(生成私鑰又名
data
-bytearray)還不夠?此功能是否會增加任何形式的安全性?
為什麼加密安全的隨機數生成器(生成私鑰又名數據字節數組)還不夠?
一個加密安全的真隨機數生成器就足夠了。此程式碼使用腰帶和吊帶方法。這在 RNG 中很常見,因為 RNG 傳統上是加密實現中最脆弱的組件之一(參見例如SmartFacts)。
意圖似乎是:如果
UseAdditionalEntropy
預設為true
, 並且additionalEntropy
通過呼叫以下兩種形式之一設置了一些不可猜測或/和真正隨機的東西AddEntropy
- 如果最初包含一些可猜測的內容,請嘗試
data
通過混合兩者(在第一個循環中)來挽救這一天- 通過應用不可逆的變換,很難從結果中“退回”。當
data
是 32 字節並且entropyIndex
從零開始,這個轉換是 $ \mathtt{data}\mapsto\operatorname{SHA-256}(\mathtt{data})\oplus\mathtt{data} $ . 給定輸出,找到輸入的唯一希望是列舉可能的輸入值¹。可以想像,第 1 步可能會適得其反,例如,如果
data
傳遞的是之前傳遞給 的 SHA-256 雜湊值AddEntropy
。
data
第 2 步略微降低了熵(如果是全熵,則減少小於 1 位,請參閱此;如果data
小於全熵,則可以忽略不計),但在上下文中這很好。此功能是否會增加任何形式的安全性?
如果呼叫上下文有缺陷,並且被使用並傳遞了一些秘密(包括隨機的和獨立於輸出的東西;或者只是在安裝時隨機生成的秘密常量)
Random.GetBytes
,它確實如此。只要和 保持(因此不會意外呼叫),這種預防措施就不太可能意外適得其反。AddEntropy``Random.GetBytes``PushEntropy``additionalEntropy``entropyIndex``private
¹ 如果我們改為
+=
在^=
SHA-256 的輪函式的最後混合步驟中,這種轉換將是可逆的。如果我們在顯示的程式碼中更改^=
為,它將危險地接近可逆。-=