從密碼中獲取排列
是否有任何“好”的方法可以從密碼/密碼片語中獲取排列?
例如,如果有人想從密碼中獲取字母的排列,那麼如何以一種聰明的方式做到這一點?我會對一種方式感興趣,即從一個密碼單詞中生成一個給定的數字,例如 7,用於 Enigma 機器的排列。
我知道如果密碼是
password
一個可以簡單地製作字母表
paswordbcefghijklmnqtuvxyz
以便排列將發送a
到p
到w
到o
到等。但這似乎不是一個非常明智的選擇。如果為兩個非常相似的密碼生成的排列非常不同,那顯然會很好。
有什麼更好的方法來做到這一點?
編輯:這不需要機械地實現。
如果我理解正確,您需要一個針對每個輸入字元串的函式 $ p $ 在字母表上分配一個排列 $ L $ .
如果元素個數 $ L $ 足夠小,置換集 $ P(L) $ 將是可列舉的。更確切地說, $ |P(L)| = |L|! $ . 存在一個滿射函式 $ f:{0,1}^k \to P(L) $ 對於每個位串 $ s $ 長度 $ k $ 分配一個排列 $ L $ , 在哪裡 $ k \gt log_2(|L|!) $ . 例如, $ f(s) = g(BS2I(s) \bmod n!) $ 和
function g Input: Large integer Output: array [L] of L x := Input; for i := 0 to (n-1) do z[i] := i; for i := n downto 1 do begin t := x mod i; x := x div i; y[n-i] := z[t]; for j := t+1 to i-1 do z[j-1] := z[j]; end; for a in L do Output[a] := I2E(y[E2I(a)]);
將起作用,前提是 $ 2^k $ 足夠大 $ n! $ 使偏差不顯著。**注意:**從觀察到每個 $ x $ 在範圍內 $ 0..n-1 $ 將產生一個獨特的序列 $ t $ 價值觀。每一步都會發生變化 $ t $ 將導致與剩餘的值不同 $ z $ 正在選擇的值。該算法緊密遵循正常證明,即 $ n $ 元素等於 $ n! $ .
但是,正如 fgrieu 在下面的評論中指出的那樣,更有效的算法是:
function g Input: Large integer Output: array [L] of L x := Input; for i := 1 to n do begin t := x mod i; x := x div i; y[i-1] := i-1; y[i-1] := y[t]; y[t] := i-1; end; for a in L do Output[a] := I2E(y[E2I(a)]);
第二種算法還將輸出唯一的排列 $ x \in {0..n-1} $ . 非正式地,這是因為每個排列 $ n $ 元素最多可以表示為一個序列 $ n $ 成對替換。該算法恰好導致序列 $ n $ 這種成對的替換保證會產生唯一的排列。
為確保兩個相關的輸入密碼不會映射到兩個相關的排列,您首先通過 PBKDF 傳遞密碼(如 fgrieu 在評論中所建議的那樣),然後再應用 $ f $ . 如果 $ |L| = 26 $ 然後 $ k = 256 $ 就足夠了(因為 $ log_2(26!) \lt 89 $ 的偏見 $ f $ 將大大低於 $ 2^{-128} $ ).
因此:
- 通過輸入密碼 $ p $ 通過 PBKDF 產生一個位串 $ s $ 位長 $ 256 $ .
- 轉變 $ s $ 為 256 位整數 $ x $ 使用標準 $ BS2I $ 功能。
- 地圖 $ x $ 對 26 個元素字母表的排列 $ L $ 使用功能 $ g $