Entropy

轉換字元集如何影響雜湊熵?

  • June 20, 2019

對於固定大小的子字元串,將大字元集散列映射到小字元集散列是否會降低熵?

我正在編寫一個涉及為網站生成密碼的 python 應用程序。在應用程序期間,我想將十六進制雜湊轉換為字母數字字元串,並獲取輸出的前 20 個字元。我想轉換為字母數字,因為大多數網站至少支持上下字母數字字元集。

我推測地映射了更大的十六進製字節字元集 $ {00…\text{ff}} $ 到較小的大寫和小寫字母數字集 $ {a…z, A…Z, 0…9} $ .

映射是通過循環回收 62 個字母數字元素來完成的,以對應 256 個字節的每個元素

$$ 00 \rightarrow a $$ $$ 01 \rightarrow b $$ $$ \vdots $$ $$ 0e \rightarrow 9 $$ $$ 0f \rightarrow a $$ $$ \vdots $$

例如,如果世界上最安全的密碼 - “密碼” - 被 sha512 消化為十六進制,這不足為奇 - $ 128 \times log_2(16) = 512 $ 位。

$$ \text{b109f3bbbc244eb82441917ed06d618}\ \text{b9008dd09b3befd1b5e07394c706a8b}\ \text{b980b1d7785e5976ec049b46df5f1326}\ \text{af5a2ea6d103fd07c95385ffab0cacbc}\ 86\ $$

由於每對十六進制數字都映射到一個字母數字上,我假設結果字母數字字元串的熵是 $ 64 \times log_2(62) = 382.5459 $ 位。

$$ \text{1j5bcKq8KdvcwVJpuiJj3efBGh5oYSp}\\text{9 e1D6GB4YeFiLHtMZCUQxdfhpvjhVmWck}\ $$

新字元串的長度只有原始字元串的一半,但熵約為原始字元串的 75%,因此在字母數字投影中每個字元的熵更多,使得

$$ \text{1j5bcKq8Kd} $$

更好的密碼

$$ \text{b109f3bbbc} $$

我是否做了任何無效的假設,或者做錯了數學?任何關於這種滿射映射是否是一個好主意的見解都將不勝感激。如果需要任何澄清或編輯,我很樂意進行 - 請在下面發表評論。

一般來說,如果一個函式 $ f $ 有碰撞,那麼它可能會減少熵:$$ H[f(X)] \leq H[X]. $$ 不等式適用於任何熵的概念——最小熵、香農熵、哈特利熵、Rényi熵等。 發生這種情況是因為如果 $ f(x_i) = f(x_j) $ 為了 $ x_i \ne x_j $ , 機率質量 $ \Pr[X = x_i] $ 和 $ \Pr[X = x_j] $ 兩者都對機率質量有貢獻 $ \Pr[f(X) = y] $ 在哪裡 $ y $ 是的共同價值 $ f(x_i) $ 和 $ f(x_j) $ . 特別地,最小熵是$$ -\log_2 \max_y \sum_{x \in f^{-1}(y)} \Pr[X = x]. $$ 這裡輸入衝突最多的輸出是 $ {\mathtt a, \mathtt b, \mathtt c, \mathtt d, \mathtt e, \mathtt f, \mathtt g, \mathtt h} $ ,每個都有五個不同的輸入( $ f^{-1}(\mathtt a) = {0,62,124,186,248} $ 等),所以在最好的情況下,如果 $ X \in {0,1,2,\dots,255} $ 具有均勻分佈,最小熵 $ f(X) $ 是 $ -\log_2 5/256 \approx 5.678 $ . 對於一串獨立的輸入 $ X_1 \mathbin| X_2 \mathbin| \cdots \mathbin| X_n $ , 串聯 $ f(X_1) \mathbin| f(X_2) \mathbin| \cdots \mathbin| f(X_n) $ 最小熵約 $ 5.678n $ . 因此,由此產生的 64 個字元的字元串最多將具有大約 363 位的最小熵。

請注意,這比來自同一字母表的統一隨機字元串要少一些,後者俱有 $ \log_2 62 $ 每個字元的熵位,或大約 $ 5.954n $ 一串中的熵位 $ n $ 獨立字元,對於 64 個字元的字元串,您計算得出的最小熵約為 384 位。


還有其他方法可以大致完成您正在做的事情:

  • 使用 base64。這是一個從八位字節字元串到字元串的單射映射 $ {\mathtt a, \mathtt b, \mathtt c, \dots, \mathtt z, \mathtt A, \mathtt B, \mathtt C, \dots, \mathtt Z, \mathtt0, \mathtt1, \mathtt2, \dots, \mathtt9, \mathtt+, \mathtt/} $ 帶有可選填充。當然,如果需要遵守強制和禁止的特殊字元,您可以更改確切的字元集。
  • 使用拒絕抽樣。來自無限的溪流 $ \operatorname{SHA512}(k \mathbin| 0) \mathbin| \operatorname{SHA512}(k \mathbin| 1) \mathbin| \operatorname{SHA512}(k \mathbin| 2) \mathbin| \dots $ ,取可接受的八位位組(例如,對圖形 US-ASCII 字元進行編碼)並拒絕不可接受的八位位組,直到您擁有所需的密碼為止。

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