從凱撒與維吉尼亞這類簡化的密碼出發,我們可以試著抽象出密碼的運作原理,方法是先辨識出它的兩個主要元件:
- 置換(permutation):一個轉換單一項目(在密碼學中是一個字母或一組位元)的函式,且每個項目都有唯一的反函式。凱撒密碼的三字母位移就是一例。
- 運作模式(mode of operation):一個利用置換來處理任意大小訊息的演算法。
凱撒密碼的模式很平凡:它只是對每個字母重複同一個置換。維吉尼亞密碼的模式則複雜些——不同位置的字母會經歷不同的置換。
置換#
多數古典密碼的做法,是把每個字母替換成另一個字母,也就是執行替換(substitution)。在凱撒與維吉尼亞密碼中,這個替換是字母表上的位移。
字母表或符號集本身可以變動:可以不是英文字母而是阿拉伯字母,可以不是字母而是單字、數字或表意文字。
資訊的表示法或編碼方式是另一回事,與安全性大致無關。我們這裡只考慮拉丁字母,因為那正是古典密碼所用的。
什麼才算置換#
密碼的替換不能是任意的替換,它必須是一個置換——也就是字母 A 到 Z 的重新排列,使每個字母都有唯一的反元素。
- 把 A、B、C、D 分別轉換成 C、A、D、B 是置換,因為每個字母都映射到另一個唯一的字母。
- 把 A、B、C、D 轉換成 D、A、A、C 不是置換,因為 B 和 C 都映射到 A。
安全置換的三個條件#
不是每個置換都安全。要安全,密碼的置換必須滿足三個條件:
置換應由金鑰決定。 這樣只要金鑰保密,置換就保密。在維吉尼亞密碼中,若你不知道金鑰,就不知道用的是 26 種置換中的哪一個,因此無法輕易解密。
不同的金鑰應產生不同的置換。 否則在沒有金鑰的情況下解密會變得更容易:如果不同金鑰導出相同置換,代表相異金鑰數少於相異置換數,破解時要試的可能性也就更少。維吉尼亞密碼中,金鑰的每個字母決定一個替換;有 26 個相異字母,就有 26 個相異置換。
置換看起來應該要像隨機的。 置換後的密文不該有任何樣式(pattern),因為樣式會讓置換對攻擊者變得可預測。維吉尼亞密碼的替換就相當可預測:一旦你判定 A 加密成 F,就能推出位移值是 5,於是也知道 B 加密成 G、C 加密成 H……。但若是隨機選出的置換,知道 A 加密成 F 只能告訴你「B 不會加密成 F」。
滿足這三個條件的置換,我們稱為安全置換(secure permutation)。
安全置換是建構安全密碼的必要條件,但不充分。密碼還需要一個運作模式來支援任意長度的訊息。
運作模式#
假設我們有一個安全置換,它把 A 換成 X、B 換成 M、N 換成 L。那麼 BANANA 會加密成 MXLXLX——每個 A 都被換成 X。
對明文中所有字母使用同一個置換,會洩漏明文中的重複字母。分析這些重複,你或許學不到整段訊息,但一定會學到一些東西。在 BANANA 這個例子裡,你不需要金鑰就能猜出明文在三個 X 位置是同一個字母、在兩個 L 位置是另一個相同字母。如果你還知道這則訊息是某種水果的名稱,你就能判定它是 BANANA 而不是 CHERRY、LYCHEE 或其他六個字母的水果。
運作模式(mode of operation,或簡稱模式)的作用,就是對重複的字母使用不同的置換,藉此緩解這種暴露。
維吉尼亞的模式仍然不夠#
維吉尼亞密碼的模式只部分解決了問題:若金鑰有 N 個字母長,每 N 個連續字母就會用到 N 個不同的置換。但密文中仍會出現樣式,因為訊息中每隔 N 個字母就會用到同一個置換——這正是頻率分析能破解維吉尼亞密碼的原因。
就算讓維吉尼亞密碼只加密與金鑰等長的明文以擊敗頻率分析,還有另一個問題:重複使用同一把金鑰會暴露明文之間的相似性。例如用金鑰 KYN,單字 TIE 與 PIE 分別加密成 DGR 與 ZGR,兩者都以相同的兩個字母 GR 結尾,洩漏了兩段明文的最後兩個字母也相同。
要建構安全的密碼,必須把安全置換與安全模式結合起來。理想上,這個組合要能阻止攻擊者學到訊息長度以外的任何資訊。
為什麼古典密碼註定不安全#
古典密碼註定不安全,因為它們受限於你在腦中或紙上能完成的運算。它們沒有電腦的算力,很容易被簡單的電腦程式破解。
根本原因在於:安全的置換無法同時滿足「運算簡單」與「描述簡短」這兩個限制。
記得置換要安全就得看起來像隨機的,而看起來像隨機最好的方式就是真的隨機——從所有置換的集合中隨機挑選。可選的置換非常多;以 26 個英文字母為例,大約有 2^88 種置換:
26! = 403291461126605635584000000 ≈ 2^88
其中 n! = n × (n − 1) × (n − 2) × ... × 3 × 2為什麼是這個數字?把置換想成重新排序的字母清單:第一個位置有 26 種選擇,第二個有 25 種,第三個有 24 種,依此類推。
這個數字非常巨大,與人體內原子的數量同一個數量級。
但古典密碼只能用到其中極小一部分——那些只需要簡單運算(例如位移)且描述簡短(像是一段短演算法或一張小查找表)的置換。問題就在這裡:
要用簡單運算得到安全置換,你可以隨機挑一個置換、把它表示成一張 25 個字母的表(足以描述 26 個字母的置換,第 26 個可略去),再靠查表來套用。但這樣就沒有簡短的描述了——例如描述 10 個不同的置換要用掉 250 個字母,而維吉尼亞密碼只需要 10 個字母。
要用簡短描述產生安全置換,你得放棄單純的位移,改用加法、乘法等更複雜的運算。這正是現代密碼的做法:給定通常 128 或 256 位元的金鑰,它們為了加密單一個字母會執行數百次位元運算。這在每秒能做數十億次位元運算的電腦上很快,但要用手算得花上好幾個小時——而且仍然會被頻率分析攻破。