超酷演算法(2):分組密碼與安全排列

威士忌發表於2015-01-16

作為開始,我假設你知道什麼是排列,簡單說就是按特定的順序對序列進行洗牌。比如,值域1-10的排列為{5,2,1,6,8,4,3,9,7,10} 。一個安全的排列是攻擊者即使有該排列的任意子集,都無法確定其它任何一個元素的順序。這裡有個簡單的例子是使用一個安全加密的偽隨機數生成器,用一個金鑰作為種子,並用它來打亂你的序列。

如果你想生成一個非常非常大的排列,一個如此大的預計算和儲存是不是不太現實?此外,你是否希望它是個安全序列?這裡有個非常巧妙的方法,我們可以使用分組密碼,使我們能夠產生超過數值範圍內的任何一個安全排列,而不必對它們進行預計算。

分組密碼,沒人不熟悉,它是密碼學中一種常見的基礎元素。它是由多塊一定長度的密文組成,密文一般為64或128位的加密串。相同的金鑰和相同的明文,它只可能生成相同的密文。超過一個塊大小的資訊使用一系列操作模式中的某一種方式加密,繼而可以針對比單個塊大許多的訊息進行安全的加密和解密。使用分組密碼加密,選擇操作模式是至關重要的。為了能生成一個安全排列,無論如何,我們只打算每次加密單個塊,所以我們不必擔心操作模式。

如果你知道分組密碼是如何運作的,你肯定能獲得一個安全的排列。將給定長度的任意塊(考慮下塊的數量非常大的情況)用唯一的方式轉換為另外一個塊,且能將它再次轉換回來。如果我們逐步加密更大的數字(1,2,3等等),我們保證能得到看上去隨機的序列,只要不重複輸入。這點很容易證明:假如它是重複的,那你會有兩個輸入數字被解碼為同一個輸出數字,這樣就不可能有獨一無二的解碼。分組密碼所持有的這些特性也正是對我們有用的特性。

你說,一切都挺好,但如果我想要一個不是2的冪次值域內的排列該如何?這裡有個聰明的小技巧,就是取一個塊長度略大於你想要的長度的分組密碼,使用上面描述的方法,逐步加密序列中的更大數值,以產生排列中的元素。當加密後的值超出你想要的排列值域之外,只需再次加密。重複這樣的方式直到你給到你想要的值域內的數值。同樣,我們能保證分組密碼的唯一性,並且我們也能保證(窮舉方式)最終獲得了一個理想值域內的數值。

很顯然,在追尋這條路之前我們需要考慮一些因素。你要選擇一個分組密碼,是不是比你想生成的序列的值域要大,最好是2的冪次。密碼值域和排列值域的比率確定了你執行的平均時間, 因此,如果密碼是你排列的值域的四倍時,你就對每個值平均需要四次加密。這可能產生問題,因為大多數密碼是64,128或者更多位。為了這個目的,我們找到適應性比較強的TEA加密演算法,它很容易構造32,64,128或者更長位的變體,並且位操作在main主迴圈那很容易調整,也可產生4的冪次長度的密碼,而無需將密碼縮短至容易被暴力破解的長度。

另外值得一提的是,雖然這個技術的目的是生成非常大的安全排列,但對那些並不注重安全的排列同樣有用 – 你的金鑰可作為生成排列的隨機種子。在許多情況下這種方法同樣有幫助,基本上它是個對映函式可以用來索引排列的數值,這樣你可以計算出該排列的任意子集的值。

最後,請記住,由於可能的排列數呈階乘級增長,你的金鑰空間肯定大大小於排列的數量。這個對於大多數應用可能並不重要,因為如此龐大的排列不可能一個個列舉過去。但是,如果你的金鑰過短,它就有可能被攻擊者利用列舉金鑰的方式來找出可能生成的排列。

更新:Yossi Oren在評論裡留了分優秀的論文連線。它涵蓋了我的描述(當然更全面)。

相關文章