Diffie-Hellman

Diffie Hellman 密鑰協議中的共享秘密有多隨機

  • May 20, 2014

值有多隨機 $ ZZ $ 在 DH 協議中

這個問題是由 Sergei 在 Stackoverflow 上展示的這種有點幼稚的 I2P 實現引發的。明顯地 $ ZZ $ 與隨機預言不同,因為第一個字節將低於或等於最高字節 $ p $ , 如果 $ p $ 使用相同的編碼 $ I2O $ (整數到八位字節串)函式。

是否有一個數學函式可以顯示第一個(最高階)有多少“熵” $ x $ 取出的字節 $ ZZ $ ?

Diffie-Hellman 密鑰交換生成的共享密鑰是乘法群模子群的隨機元素 $ p $ 由產生 $ g $ .

特別是,對於 $ g $ 和 $ p $ 按照RFC 2631 第 2.2 節中的規定選擇,即 $ p = jq+1 $ , 在哪裡 $ q $ 和 $ p $ 都是素數, $ j $ 是一個小數(通常是 2,使得 $ p $ 作為安全素數)和 $ g $ 生成訂單 $ q $ 子群模 $ p $ ,這個子群包含 $ q $ 因此,元素和共享秘密(當然,假設私鑰是適當生成的)具有 $ \log_2 q $ 一點點的熵。

將此熵提取為有用形式的推薦方法是對共享密鑰進行散列,或者更好的是,將其輸入到HKDF (RFC 5869)密鑰派生函式中。您要問的是,如果我們簡單地採用共享密鑰的二進制編碼的第一個(或最後一個)256 位並將它們用作 AES-256 密鑰,會有多糟糕?

有點令人驚訝的是,我的回答是“還不錯”。我們可能無法從秘密中得到 256 位的熵,但我們應該至少得到 247 位左右(假設秘密足夠長當然,首先要有這麼多位),這對於任何實際目的來說仍然足夠了。


具體來說,我們假設 $ p $ 是一個安全素數(即 $ j=2 $ ),並且秘密被填充到編碼所需的最小字節數 $ p $ ,如 RFC 2631 中所指定。因此,填充的秘密將是一個位串 $ n = 8 \cdot \lceil (\log_2 (p+1)) /8 \rceil \le \log_2 p + 8 $ 位,並將包含$$ m = \log_2 q = \log_2((p-1)/2) = \log_2(p-1)-1 \approx \log_2 p - 1 $$一點點的熵。當我們將秘密截斷為 256 位時,我們會丟棄一些熵,但最多只能從長度中刪除的位。因此,截斷的秘密將至少包含 $ m - (n - 256) = 256 - (n - m) \ge 256 - 9 = 247 $ 一點點的熵。

現在,在您引用的程式碼中,秘密顯然沒有填充到固定數量的字節,而是刪除了前導零字節。然而,至少假設 $ q \gg 2^{256} $ ,這仍然應該沒有太大的區別。(事實上,在某些情況下,它甚至可能略微增加截斷後留下的熵。)

要了解原因,讓 $ k = 8 \cdot \lceil (\log_2(z+1))/8 \rceil $ 是對秘密進行編碼所需的位數 $ z $ . 首先,我們將觀察到 $ {\rm Pr}[k < 256] = {\rm Pr}[z < 2^{256}] \le 2^{256} / q = 2^{256-\log_2 q} $ . 比如說, $ q > 2^{336} $ ,這個機率可以忽略不計(小於 $ 2^{-80} $ )。因此,對於足夠大 $ q $ ,我們可以安全地假設 $ k \ge 256 $ .

現在,對於每個可能的長度 $ k $ , 秘密 $ z $ 位於區間 $ 2^{k-8} \le z < 2^k $ . 使用與上述相同的論點,我們可以證明,對於任何給定的 $ k $ , $ z $ 必須至少有 $ k - 9 $ 熵位,並且將其截斷為 256 位必須至少留下 $ 256 - 9 = 247 $ 一點點的熵。因為我們將至少有 247 位熵,無論 $ k $ (除了可以忽略不計的情況),我們總共將有至少 247 位的熵。

(為了 $ j > 2 $ , 常數 $ 9 $ 上面變成 $ 8 + \log_2 j $ 相反,但這沒什麼區別,除非 $ j $ 是巨大的,它通常不應該是。)


綜上所述,以上都不應被視為反對使用適當的 KDF 將 Diffie-Hellman 機密轉換為關鍵材料的論據。你絕對應該這樣做,如果只是因為 a) 標準是這樣說的,b) 它仍然更安全,c) 它提供了其他好處,比如加鹽。儘管如此,似乎簡單地使用原始截斷的 D-H 共享密鑰作為加密密鑰可能並不僅僅基於閱讀 RFC 所假設的那麼糟糕。

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