決定把密碼學領域的東西拿出來用更完整的方式重講一次。
只要使用到 3C 產品,我們的生活總是無法和「加密」這件事情脫離關係,因為這攸關到你的資訊安全。
你有沒有遇過需要把壓縮檔鎖上一層密碼的經驗呢?我們都知道,如果電腦裡面有重要的文件(比如你的遊戲帳號密碼),為了不想讓其他使用電腦的人窺探內容,我們可以利用 7-zip 或者是 WinRAR 等常見的檔案壓縮軟體來把這些機密檔案加上一層鎖。
。資料是如何被電腦儲存的?
要想瞭解資料怎麼被加密,就要先知道這些資料是如何被儲存在電子產品裡面。
先前在《跟著豬腳 C 起來:用電腦來操控資料吧》這篇的前半段其實就已經講過,在電腦的世界裡面一般用 1 或 0、每八位一組的二元組合來表示資料。基本上,電腦裡面可呈現的資料全都是用這樣的組合來儲存,只是為了方便編輯,我們習慣用十六進位來表示。
可以在專用的編輯器裡面看到這些資料是怎麼被儲存的:
畢竟之前已經講過了,這段算是個簡單的回顧,就到此打住吧。
。舊時的加密方法
這篇文我們不談壓縮檔怎麼壓縮資料,就單純聚焦在「加密」這件事上面。首先要有一個觀念:「所謂的加密並不是直接幫資料加上一層密碼鎖,而是把密碼作為規則直接把原來的資料洗牌。」
最早的加密方法可以追溯到好幾千年以前。不過,古典的密碼學當中最有代表性的就是凱撒加密法了。我們都知道,英文從 A~Z 總共有 26 個基本字母,而且是有序的。凱撒加密法就是利用這個特點:把 A~Z 的字母依序往後推,就成了加密過的結果。
比如說,你和班上的某個女同學事先約定好:「我們之間接下來傳的紙條都使用英文,並且會把每個字都往後推 7 個字母。要想看懂原來的內容,只要把每個字往前推 7 個字母就可以了。」
於是,某天你想傳給她「I LOVE YOU」這樣的紙條。我們知道,把字母 I 往後推 7 個字母會是 P,把 L 往後推 7 個字母會是 S,把 Y 往後推 7 個字母(Z 之後接著從 A 開始算)會是 F……我們就得到了「P SVCL FVB」這樣的密文。
如此一來,當她拿到紙條以後,只要把「P SVCL FVB」每個字反過來往回推 7 個字母,就可以知道你想告訴她「I LOVE YOU」了,而且至少不會被傳遞路徑上的同學一眼瞥懂紙條的內容。
然而,這種方法還不夠安全。如果這條密文被人複製了一份下來,只要把解密的所有可能列出,一定會有其中一份是原來的明文,而且最多只需要嘗試 25 次:
對於一個有一定英文基礎的人來說,這份明文一定是很顯眼的。所以,如果想要達到絕對的安全性,光靠這種方式是不夠的。
當然,凱撒加密法也有很多種變體,但規則大同小異就是了。
。邏輯閘和加密的關聯
到了現代,電腦和網路的發展使得加密的需求越來越大,科學家便想辦法讓電腦實現資料加密——他們發現,邏輯閘當中的「XOR」運算正好適合拿來做這件事。
邏輯閘是什麼?可以想像,如果我們今天想要判斷多個條件,就會需要同時檢查這些條件成立與否,最後得到結果。比如說,假設有個女生 A,她希望找個有房「而且」有車的人嫁了,那下面四種條件的人就會分別有這樣的結果:
有房、有車 → 過關
有房、沒車 → 淘汰
沒房、有車 → 淘汰
沒房、沒車 → 淘汰
如果我們用 1 和 0 分別代表有或無,拿到「且」邏輯閘的運算上面就會是:
1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0
假設今天有個女生 B,要求沒有那麼高,她希望找個有房「或是」有車的人嫁了,四種條件的人就會得到這樣的結果:
有房、有車 → 過關
有房、沒車 → 過關
沒房、有車 → 過關
沒房、沒車 → 淘汰
用 1 和 0 來表示,就會是:
1 OR 1 = 1
1 OR 0 = 1
0 OR 1 = 1
0 OR 0 = 0
這就是「且」邏輯閘(AND)和「或」邏輯閘(OR)的基本概念。電腦除了這兩種邏輯閘以外,還有各種邏輯閘:NAND、NOR、XOR、XNOR、NOT……其中的 XOR 邏輯閘(異或)就恰好符合加密的要求:
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
看起來沒有什麼特別的,但這樣的基礎,導致 XOR 具有這樣的運算性質:
(A XOR B) XOR B = A
也就是說,我們計算 A XOR B 會得到 C,也可以透過 C XOR B 恢復為原來的 A。這種規則正是資料加密所需要的:「用一把鑰匙把資料『上鎖』,也可以透過同樣一把鑰匙把這些資料『解鎖』。」
比如說,我們今天有兩個位元組的資料 [205, 180],我們想要使用密鑰 [156, 223] 來加密,那我們就可以透過 XOR 運算,把明文轉換為密文:
我們說過,在目前的一般電腦裡都是使用 1 或 0 的二進位表示法來表示一組數字,所以我們在做 XOR 運算之前當然要先把 205 轉換成 11001101(以此類推),上圖正是在演示:
205 XOR 156 = 81
180 XOR 223 = 107
我們把本來的 [205, 180] 用 [156, 223] 加密,得到了長得完全不一樣的 [81, 107],得到的這份結果就是經過加密的密文;反過來我們如果計算 [81, 107] XOR [156, 223],就會得到原來的 [205, 180] 了:
如此一來,其他人就算知道了你的密文是 [81, 107],只要他們沒有密鑰,就沒有辦法還原出你本來就要傳達的 [205, 180]。
這樣的流程要寫成電腦程式也不難(「^」符號在 C 語言裡是 XOR 的意思),一下就能算出它們的 XOR 運算結果:
我們可以從明文和密鑰計算出密文:
201 XOR 12 = 197
44 XOR 11 = 39
……
4 XOR 97 = 101
只要反過來做,就可以從密文和密鑰計算出明文,這就成了簡單的加密、解密流程。
。經典的對稱式加密算法:RC4
像上面提到的這種概念很好理解,我們可以像一般的鎖一樣,用同一把鑰匙把它上鎖或解鎖,這種類型的加密稱為「對稱式加密」。
嚴格來講,剛才舉例的 [156, 223] 在密碼學上並不是真正的「密鑰」。為了保證「可以輕易地獲得一定的安全性」,加密演算法通常會把你設定的密碼當作遊戲規則,用這個規則間接決定出一組更複雜的密鑰。
以 1987 年被發明出來、曾經被用作無線網路加密標準的 RC4 加密算法為例。假設今天我們設定了密碼「aabbcc123」,它在電腦裡就是 [97, 97, 98, 98, 99, 99, 49, 50, 51] 這麼一串長度為 9 的資料。
RC4 演算法在正式開始加密之前,會先產生一組長度為 256、有序的乾淨資料:
令 key = [97, 97, 98, 98, 99, 99, 49, 50, 51]
令 s = [0, 1, 2, 3, 4, ..., 253, 254, 255]
令 j 為 0
接著:
令 i 為 0、令 j 為某個值
把 s[i] 和 s[j] 的值交換
令 i 為 1、令 j 為某個值
把 s[i] 和 s[j] 的值交換
令 i 為 2、令 j 為某個值
把 s[i] 和 s[j] 的值交換
……
上面所謂的「某個值」,是用 j、i、s、key 共同決定的 0~255 之間的數字。這樣的做法保證 S-box 裡面的每個元素都會被交換至少一次。用電腦程式模擬一次,可以看到在重複 256 次的交換以後,S-box 裡面的元素順序就被打得非常混亂了:
上半部是乾淨的 S-box,下半部是被打亂過的 S-box。剛才提到的「aabbcc123」就決定了 S-box 會被打亂成下半部的模樣,看起來毫無規律、很像隨機產生,但每次輸入一樣的密鑰就一定會得到相同的 S-box,所以這又可以被稱為「偽隨機」。
這個初步決定好的 S-box 的內容,就決定了之後加密過程當中明文要做 XOR 運算的對象。RC4 算法不只這樣,它甚至還會一邊加密、一邊繼續打亂 S-box,如此循環利用,就可以用來加密任意長度的資料。
至於上述的「某個值」和「後續打亂的方式」具體是如何決定,對本篇來說屬於不太重要的細節,有興趣的再自己去找來研究吧。
。關於對稱式加密算法
市面上眾多加密算法當中,剛才舉例的 RC4 算是對稱式加密算法當中最好理解的一種。不過,即便已經做得如此複雜,RC4 算法仍然在 2015 年被宣布其密文可以在數天之內被成功破解。
你所用的壓縮檔 rar、7z 格式,一般情況下都是使用 AES(進階加密標準)來幫資料上鎖。AES 的加密算法也是用 XOR 邏輯閘的特性來加密、解密資料,但 AES 的步驟跟 RC4 比起來又更加複雜了,光是在開始把資料加密前的準備工作,就包括了 AddRoundKey、SubBytes、ShiftRows、MixColumns 等等的步驟,而且還會重複循環很多次,保證這些用來加密的元素被打得夠亂、不容易被用簡單的方式破譯。
不過,有鑑於 AES 的加密步驟實在太複雜,光是解釋步驟恐怕就要花上好幾千字的篇幅,所以我想只要讓大家稍微感受一下對稱式加密是怎麼運作的就足夠。
到目前為止,只要你選用的密碼夠長、夠複雜、夠特別,要想用一般的電腦破解 rar 或 7z 檔案是不太可能的。AES 算法問世至今已有 20 多年,在沒有數學家發現漏洞的狀況下,要想破解它大概就要等到量子電腦發展成熟才有機會了。
也就是說,如果你在市面上看到了任何宣稱「能夠繞過壓縮檔加密保護」的程式,最好還是不要輕易相信而下載來使用——畢竟,最迷人的,最危險。