[譯] 密碼學速成課

Xat_MassacrE發表於2019-05-05

長久以來,密碼學的內部工作原理往往被認為是專家和數學家所獨有的領域,而它的技術性也很大程度上被歸功於魔法。但是,如果能把現代密碼學複雜的本質講出來,其實密碼學也是可以理解的。然而,由於對英國提出的『加密禁令』和澳大利亞提出的『援助與訪問法案』等主題缺乏瞭解而導致的許多全球運動,顯然是弊大於利的做法。

如果你想要了解密碼學,本文將會以速成課的形式講到你需要知道的幾乎所有知識。下面我將簡要介紹各種加密系統的歷史,並著重講一下密碼學中三種最流行的方向:流密碼、分組密碼以及公鑰密碼系統。

密碼

密碼是密碼學的基石。密碼就是一組處理資訊加密和解密的演算法。一個加密演算法(E)需要一個金鑰(k)和一段資訊(m),就可以產生一段密文(c)。同樣的,一個解密演算法(D)需要一個金鑰(k)和一個之前的密文(c)。可以表示成下面的形式:

加密演算法 E 和解密演算法 D

這意味著要成為一個密碼,它必須滿足下面的等式才可以成功解密:

[譯] 密碼學速成課

這個等式說明了如果你是用金鑰 K 加密一段資訊,那麼你就可以通過金鑰 K 解密出相同的資訊。

作為最古老也最簡單的密碼之一的凱撒密碼,就是用字母表中固定偏移位置的字母替換一段資訊中的每一個對應的字母的加密方法。

[譯] 密碼學速成課

在下面的例子中,資訊中的每個字母就移動了三個字元:

[譯] 密碼學速成課

這個密碼可以用數學方法表示成下面的形式:

[譯] 密碼學速成課

雖然這種加密方式符合我們對密碼的定義,但是它一點也不安全。如果一個攻擊者知道使用的是凱撒密碼,那麼他只需要嘗試所有的 25 種組合就可以破譯這個密碼。即使他不知道使用的是凱撒密碼,他也可以通過觀察密文中的字母模式來發現使用的就是凱撒密碼。

為了接下來要討論的更安全的加密演算法,我們不得不介紹一種運算:XOR(異或)。

XOR

XOR 或者說『異或』門是一種布林數字邏輯閘,它接收兩個輸入值 0 或者 1,如果這兩個輸入值不同則返回 1,如果相同則返回 0。它可以用下面的真值表來表示所有輸入輸出的可能:

[譯] 密碼學速成課

這個運算常常用符號⊕來表示,就像下面這樣:

0 ⊕ 0 = 0,

0 ⊕ 1 = 1,

1 ⊕ 0 = 1,

1 ⊕ 1 = 0

XOR 有以下幾個重要的性質:

  1. 結合律:a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c
  2. 與自身運算得 0:a ⊕ a = 0
  3. 與 0 運算得它本身:a ⊕ 0 = a

這就意味著 a ⊕ b ⊕ a = b,因為根據上面的性質和法則我們知道 a ⊕ a ⊕ b 就等於 0 ⊕ b 等於 b。有一點很重要,那就是這個運算只對零和一有效,所有其他進位制的數字必須要先轉換成二進位制。

87 ⊕ 73 = 1010111b ⊕ 1001001b = 0011110b = 30

現在我們可以開始講我們第一個安全的密碼了。

一次性密碼本(One-time pads)

根據 Frank Miller 在 1882 年的描述,一次性密碼本(同時也叫 Vernam 密碼)就是用金鑰和原文進行 XOR 來加密的,然後再用金鑰和密文的 XOR 來解密獲得原文。根據上面的屬性,這樣做顯然是沒有問題的,因為:a ⊕ b ⊕ a = b。一次性密碼本定義的這一組加密演算法可以用下面的式子表示:

[譯] 密碼學速成課

這對密碼的相容方程可以用下面的式子證明:

[譯] 密碼學速成課

接下來,我們將會通過一個簡單的例子來展示一次性密碼本用起來有多簡單。比如我我們要加密一個單詞『Message』。第一步是將這個單詞轉換成二進位制(只有零和一的表示形式)。我們可以根據 ASCII character set 來轉換每一個字母。

[譯] 密碼學速成課

現在我們需要一個隨機的 56 位的金鑰,用來與原文進行 XOR 運算。在這裡金鑰儘可能的隨機是很重要的。

[譯] 密碼學速成課

然後我們對原文的每一位進行 XOR 的運算。

[譯] 密碼學速成課

得到的結果就是我們的密文。而要解開這段密文的話,我們只需要做同樣的操作,然後再通過 ASCII 轉換成字母就大功告成了。

[譯] 密碼學速成課

這個密碼使用和理解起來都不難,但是它還有一個有趣的特性。那就是一次性密碼本擁有完美的保密性,這意味著如果一個攻擊者只知道密文(也就是 m⊕k 的結果),那麼在數學上想要破譯獲得原文是完全不可能的。

現在我們有了一個甚至可以手動完成的簡單易懂的密碼,而且它還是數學層面上不能破解的。那麼為什麼我們還開發了別的密碼系統呢?原因在於,雖然一次性密碼本有效且易用,但是它有幾個致命的缺點。

第一個主要的問題就是對於任何被髮出去的資訊,金鑰長度必須大於或等於原文的長度。對於接收者來說,為了能夠成功的解密,必須存在一個安全的能夠給接發雙方提供傳輸金鑰的通道。在這種情況下,還不如直接在安全通道上傳輸原始資訊。

這個問題還會因為第二個缺點而更加惡化,而第二個缺點就源自於它的名稱。一次性密碼本的金鑰只能使用一次,這意味著每一條資訊都需要通過唯一且隨機的金鑰來加密。而如果用同樣的金鑰來加密多條資訊的話,會導致一個巨大的問題,這個問題還可以很容易的用數學來證明。

讓我們假設有兩條資訊 m1 和 m2,他們使用同樣的金鑰 K 來加密。那麼我們可以通過 XOR 兩條密文來得到下面的結果。

[譯] 密碼學速成課

這樣我們就獲得了 m1⊕m2。而攻擊者則可以基於這個結果進行各種各樣的分析,例如統計分析、頻率分析、模式匹配或者使用這篇論文中提到的自然語言處理。這裡我不會詳細的解釋這樣為什麼是不安全的,但是如果你感興趣的話,可以閱讀這個答案,它生動形象的解釋了為什麼這樣加密是不安全的。而同樣的金鑰用來加密的次數越多(比如三次或者四次),顯然就會越不安全。

現在我們已經瞭解了 XOR 加密和一次性密碼本的基礎知識,接下來我們就可以講一個更實用的加密方法了。

流密碼

一次性密碼本最大的優點就是它擁有完美的保密性,這意味著如果攻擊者只有密文的話,他是不可能破譯獲得原文的。然而,擁有完美保密性的同時就意味著金鑰長度必須大於或等於原文長度。這就讓一次性密碼本變得非常不實用,因為如果接收雙方擁有一個安全通道來傳輸金鑰,那麼他們顯然可以用同樣的機制來傳輸原文。

為了讓一次性密碼本更加實用,接下來讓我們介紹『流密碼』。流密碼的關鍵點在於用『偽隨機』金鑰來代替一次性密碼本的『隨機』金鑰,也就是說現在要和資訊進行 XOR 的金鑰是由密碼安全的偽隨機數生成器或者 CSPRNG 生成的。(注意:這不同於偽隨機數生成器,因為由 CSPRNG 生成的資料必須與真隨機數沒有區別)。

CSPRNG 是一個簡單的演算法(或者說函式),它可以生成大量的數字,並且非常接近隨機數的性質。生成隨機數是非常困難,CSPRNG 則是依賴一個種子來決定初始狀態的(同時這也決定了未來生成的數字)。這個演算法允許通過相對較小的初始種子(比如一個 128 位的種子可以生成幾個 G 的隨機資料)生成巨大量的隨機數。如果初始種子被知道了,那麼所有的子序列數字的生成也就被知道了,也就是說 CSPRNG 是確定性的。因為這個原因,所以生成的數字有多隨機就取決於初始種子有多隨機了。

為了讓一次性密碼本有更強的實用性,我們可以將金鑰替換成偽隨機數生成器生成的我們想要長度的數字,並且可以把初始種子作為一個新的金鑰。因為 CSPRNG 是確定性的,使用同樣的初始種子會獲得同樣的輸出。

讓我們說的更明白一點,這是一個傳統的一次性密碼本:

[譯] 密碼學速成課

給定一個偽隨機數生成器 G(K),我們可以用下面的方法來替換 K:

[譯] 密碼學速成課

(注意,這個例子只是一種型別的流密碼,叫做同步序列密碼。還有一個類似的叫做自同步序列密碼,它使用密文中前面的數字來計算加密金鑰的每一位數字。

這樣實用性方面就比一次性密碼本高多了,也就是說現在金鑰可以比原文短很多,這樣金鑰的分發也會更好管理。然而,這種方法還是有一個缺點。

那就是替換金鑰之後我們的密碼已經不再擁有完美的保密性了,因為金鑰比原文短。所以現在安全的流密碼都是依賴於不可預測的隨機數生成器。如果 CSPRNG 的輸出是可以預測的話,那麼原文就會被破譯。這裡有幾個著名的使用弱流密碼的加密系統。

802.11b WEP:WEP 是一個通過 WIFI 加密資料的演算法,它使用被稱為 RC4 的流密碼。因為在流密碼中同樣的金鑰不能被使用多次,所以長期的安全金鑰用一個隨時變化的值 IV 來串聯。然而,IV 只有 24 位,也就是說在加密 5000 條資訊之後,同樣的金鑰就會有 50% 的機會被再次使用。

CSS:Content Scramble System 作為一種數字許可權管理的形式被用來加密 DVD,以此來拒絕非授權的內容訪問。CSS 使用一個 40 位的金鑰,而這個金鑰由於只有較小的金鑰空間所以可以相對快速的被暴力破解。(雖然金鑰只有 40 位,但是因為 CSPRNG 技術的關係,只有在生成 17 位的組合之後這個系統才可以被破解。)

以上已經幾乎涵蓋了流密碼的全部內容,下面讓我們進入分組密碼。

分組密碼

分組密碼是另一種加解密資料的方法。一個分組密碼由兩個演算法構成,E 和 D 分別是用來加密和解密的(並且使用同一個金鑰 K)。

[譯] 密碼學速成課

分組密碼主要的知識點在於輸入文字的長度總是和結果密文的長度相等也就是固定大小。這個大小就是 Block Size,它取決於你使用的是哪一種分組密碼。還有,金鑰 K 的長度(Key Size)也是固定的。有兩個很常見的分組密碼,他們分別是 3DES(Block Size 是 64 位,Key Size 是 168 位)和 AES(Block Size 是 128 位, Key Size 是 128、192 或 256 位)。

分組密碼也被稱作金鑰置換或者偽隨機置換,因為它將每一個可能的塊都對映到一些其他的塊上。這個過程是通過金鑰來處理的,金鑰決定了哪一個輸入塊對映到哪一個相對應的密文塊上面。因為這是一對一的置換,所以如果知道金鑰的話,密文就可以被解密出來。

第一個廣為人知的分組密碼是 DES(Data Encryption Standard),它是上世紀 70 年代由 IBM 開發的,然後很快人們就發現了它是不安全的,於是就產生了 3DES,而 3DES 也好景不常,就被替換成了 AES(Advanced Encryption Standard),AES 是在美國國家標準與技術研究院呼籲新標準的分組密碼後於 1997 年開發的。這裡我們會著重講一下 AES,因為它是現在最常用的分組密碼,而 DES 和 3DES 就顯得相形見絀了。

現在讓我們看一下 AES 是如何工作的。為了簡單起見,這裡會跳過一些技術細節。如果你想更深入的瞭解 AES 的相關內容,請檢視這篇文章

AES 和大部分分組密碼一樣都是通過迭代(就是將輸入的文字與一系列密碼反覆的迭代計算)來工作的。第一步就是將金鑰 K(通常來說是 128、192 或者 256 位,這裡我們只關注 AES 的 128 位)作為輸入,然後將它擴充成一系列環形金鑰用來加密我們的資訊。

[譯] 密碼學速成課

在這裡,我們將 128 位(也就是 16 個位元組)的輸入金鑰利用例如 Rijndael key schedule 的金鑰擴充演算法擴充成 11 個 16 位元組的金鑰。然後我們將每一輪的金鑰 kₙ 和資訊 m 作為輸入,通過函式 R(kₙ, m) 和之前生成的每一個金鑰將資訊加密 10次。

因為 AES 是 128 位的塊大小,所以我們可以將資訊 m 用一個 4x4 的位元組矩陣來表示。同時我們也可以將每一輪的金鑰用 4x4 的矩陣來表示,這樣他們就可以通過代表訊息體的單元格來進行 XOR 運算。

[譯] 密碼學速成課

首先,輸入的資訊和第一輪金鑰進行 XOR,然後將得到的結果使用下面幾個函式進行處理:ByteSubShiftRows 以及 MixColumns(這幾個步驟下面會講到),最後就會得到最新的訊息體。接著我們使用每一輪的金鑰重複這些步驟 10 次,唯一的區別就是最後一輪不做 MixColumn 處理。最後的訊息體再與第 11 輪的金鑰進行 XOR 得到我們的結果密文。下面就是之前三個步驟的簡要說明:

ByteSub:訊息體矩陣中的每一個位元組都會用 Substitution Box 中定義的關聯位元組來替換。

[譯] 密碼學速成課

舉個例子,9a 會替換成 b8

ShiftRow:每一行都會移動一個確定的數量。第一行不移動,第二行向左移動一次,第三行向左移動兩次,第四行向左移動3次。

[譯] 密碼學速成課

MixColumns:訊息體矩陣的每一列都要進行一個線性變換。

現在我們終於可以使用 AES 來加密資料了。但是你很快就會發現這裡有一個很明顯的限制,就是你不能使用 AES 來一次性加密超過 128 位(16位元組)大小的資訊。而為了加密超過 16 位元組的資訊我們還需要介紹一個概念:工作模式

工作模式

一次性加密超過 128 位的資訊有各種各樣的方法(或者說工作模式)。其中最簡單就是著名的電子密碼本,也叫做 ECB。

ECB

ECB 是使用分組密碼加密大量資料最簡單的工作模式。它將資訊簡單的分成 16 位元組的區塊,然後使用金鑰將這些區塊分別加密。當然了,為了滿足 16 位元組的劃分,原文將不得不進行一些填充。舉例來說就是,一個 28 位元組的資訊需要額外的 4 個位元組的填充才可以分成兩個 16 位元組的區塊。在資訊被分割成區塊之後,每一個區塊都會使用金鑰分別加密。

[譯] 密碼學速成課

雖然這很容易理解,但是也帶來了一個明顯的問題。因為同樣的原文區塊將會生成同樣的密文區塊,這種模式很容易被發現。比如下面使用 ECB 加密的點陣圖:

[譯] 密碼學速成課

相同資訊區域加密後仍然是相同的,所以這樣常用的模式仍然可以被分辨出來。為了消除這個影響,我們需要使用一種更加安全的工作模式。

CBC

CBC(Cipher Block Chaining)和 ECB 的工作方式很相似,只有一點點的不同。那就是在原文的每一個區塊被加密之前先與上一個區塊的密文進行 XOR 運算,這樣就可以讓每一個原文的區塊都是唯一的。而對於第一個區塊來說,就是用原文和一個隨機生成的 IV(Initialisation Vector)進行 XOR。

[譯] 密碼學速成課

我們再加密之前的那個點陣圖來看看,很顯然,這樣在直覺上就安全多了。

[譯] 密碼學速成課

現在我們已經講了兩種主要的工作模式,還有一些其他的工作模式如果你感興趣的話可以在這裡獲得更多的資訊。

以上就是關於分組密碼我們需要知道的全部內容了,接下來讓我們進入密碼學中最後一個重要的領域。

公鑰密碼系統

之前我們講到的所有的加密技術都是對稱加密,這意味著加密和解密使用的都是同樣的金鑰。而公鑰密碼系統,也就是非對稱加密使用的是由『公鑰』和『私鑰』組成的金鑰對,並且允許在不安全的通道上進行傳輸。這部分馬上就會講到。

公鑰密碼系統常常用來加密伺服器之間的通訊,比如傳送郵件和瀏覽網頁。但是為了簡單起見我們用 Alice 和 Bob 來進行說明:

[譯] 密碼學速成課

這裡我們有兩個使用者,Alice 和 Bob 在相互發訊息。這裡雖然我們用兩個使用者來訊息來類比,但是實際上也可以當成是使用者和網頁以及郵箱伺服器進行通訊(或者其他的安全通訊)。

現在 Alice 和 Bob 可以自由暢通的進行交流。讓我們假設這裡有一個偷聽者可以偷聽到所有的對話。這個偷聽者只能偷聽資訊不能影響資料。

[譯] 密碼學速成課

在這裡,所有傳送的資料都可以被攻擊者看見,但是他不能篡改資訊。在這種情況下,Alice 和 Bob 就不能進行敏感和保密的資訊交流,因為所有的資訊都會被攻擊者得到。

讓我們試試之前討論的對稱加密,但是並沒有用。

[譯] 密碼學速成課

這種方法完全沒有用,因為攻擊者可以輕鬆的截獲金鑰,並用它來解密。Alice 和 Bob 可以用公鑰密碼系統來避免這種情況,但是什麼是公鑰密碼系統呢?

什麼是公鑰密碼系統?

公鑰密碼系統是通過使用者生成的一對金鑰來工作的:一個公鑰,一個私鑰。公鑰可以廣泛傳播並且公開分發,而私鑰只有使用者本人知道。在這個系統中,任何人都可以用接收者的公鑰對資訊進行加密,但是這個密文只能用接收者的私鑰解密。

[譯] 密碼學速成課

之所以換成非對稱加密會有用是因為用來解密的金鑰一直是保密的,它永遠都不用在通道上傳輸。就像你這裡看到的,使用這個技術這個解決一部分之前的偷聽的問題:

[譯] 密碼學速成課

即使攻擊者可以截獲到 Alice 和 Bob 的所有傳輸資訊,他也不能解密任何訊息,因為他並沒有獲得有關私鑰的任何資訊。

哇哦,這聽起來棒極了,但是這又引出了另一個主要的安全隱患。到目前為止,我們僅僅假設了攻擊者可以偷聽對話,但是不能修改傳送的資料。然而如果攻擊者可以纂改傳輸的資訊的話,他們就可以進行中間人攻擊了。如果 Alice 和 Bob 使用普通的郵件交流,那麼就意味著攻擊者就是郵局的工作人員。或者當他們使用電腦網路的時候,攻擊者可能是 ISP 的工作人員或者有能力接入被使用的網路裝置的工作人員。

[譯] 密碼學速成課

在這種情況下,攻擊者可以將 Alice 的公鑰儲存下來,然後把自己的公鑰傳送給 Bob。當 Bob 加密了他想傳送給 Alice 的資訊的時候,實際上他把這條資訊發給了攻擊者,而攻擊者就可以在傳送給 Alice 之前獲取到這條資訊,然後纂改這條資訊。

這種攻擊之所以可以成功是因為兩個主要的缺陷。分別是完整性認證性的缺失,也就是說使用者沒辦法確認一條資訊有沒有受到干擾,同時也沒有辦法確保接收到的資訊就是自己想要的使用者傳送的。而這些缺陷可以通過電子簽名認證中心來解決。

電子簽名

電子簽名就是一種確保資訊的內容沒有被篡改的方法。就像之前提到的那樣,一條被使用者公鑰加密過的資訊只能被它的私鑰解密,反之亦然。一條被使用者私鑰加密的資訊也只能被它的公鑰解密,所以如果 Alice 可以用她的私鑰加密一條資訊併傳送給 Bob 的話,那麼 Bob 就可以用她的公鑰來解密,這樣就可以確認資訊的建立者確實擁有 Alice 的私鑰。這個過程被稱為『簽名』。

[譯] 密碼學速成課

因為可以對整個資訊進行簽名,所以通常來說更有效和簡潔的方法就是對資訊的加密雜湊進行簽名然後把它包含在資訊裡面,這樣就可以確保資訊在建立之後就沒有被更改過了。

注意這裡有大量的簡化,因為『使用私鑰加密』完全就是 RSA,而其他的加密系統例如 Diffie-Hellman 或者 ECC 使用的是完全不同的簽名演算法例如 ECDSA

但是即使我們不考慮任何的簽名演算法,目前我們也只是解決了一個問題。Bob 現在可以安全的確認他收到的資訊是由私鑰的擁有者傳送的,並且這個資訊沒有被篡改。但是,Bob 仍然無法確認他收到的就是 Alice 的公鑰。為了解決這個問題,我們需要介紹認證中心

認證中心

CA(Certificate Authority)是一個可以進行電子簽名以及針對使用者和實體釋出公鑰的可信第三方。

[譯] 密碼學速成課

這是用認證中心自己的私鑰製作的,所以任何人都可以確定一個證書是否是由可信的認證中心所釋出。因此是否信任一個使用者取決於 CA 金鑰的有效性。

實際上,這些證書最常見的用途就是保護網路流量。當你到達一個使用 HTTPS 的網頁時,你可以在瀏覽器中檢視它的數字證書。

[譯] 密碼學速成課

這個系統完全依賴於認證中心釋出的證書,所以大部分裝置和電腦都會預裝可信認證中心的清單以及他們的公鑰。

[譯] 密碼學速成課

這篇文章已經夠長了,所以我們將不會再講解公鑰加密系統內部的工作原理了。感興趣的話這篇文章詳細的講解了 RSA 這個同時提供了保密和簽名的加密系統。

流密碼、分組密碼和公鑰加密系統有個明顯的差異,那就是流密碼和分組密碼都是對原文的單獨的位和位元組進行處理,而公鑰加密系統則是隻對數字進行處理。這意味著任何資訊在加密之前都要轉換成數字。所以公鑰加密系統在加密大量資料時是低效的。而為了讓加密大量資料的效率更高,我們可以將對稱加密和非對稱加密結合在一起。

這個方法就叫做 PGP。在 PGP 中,資訊是由隨機生成金鑰的分組密碼進行加密的,然後再將這個金鑰用接收者的公鑰進行加密。這樣密文中就包含了一個加密的隨機金鑰。

[譯] 密碼學速成課

這樣就高效多了,因為分組密碼在加密大量資料時有優勢,而非對稱加密用來加密解密需要的金鑰。這部分仍然屬於公鑰密碼系統,因為用來解密的金鑰只能通過私鑰的擁有者來獲得。

接下來

感謝大家能夠看到這裡,本文到這裡也就要結束了。到目前為止,你應該可以很好的理解流密碼、分組密碼和公鑰密碼系統了,同時這也將幫助你更好的瞭解現代密碼學的狀態。

對於那些想了解更多的同學,我強烈建議去學習史丹佛大學的線上課程 Cryptography I Course,這堂課將會對密碼學的技術和理論進行更深入的講解。還有一個很有用的材料是一本書 Crypto 101,這本書將會講到密碼學中很多有用的地方以及如何發現加密系統中一些常見的缺陷。而那些對利用程式設計對現實世界的加密系統進行展示攻擊感興趣的同學可以看看這個 Cryptopals challenges

相關文章