長久以來,密碼學的內部工做原理每每被認爲是專家和數學家所獨有的領域,而它的技術性也很大程度上被歸功於魔法。可是,若是能把現代密碼學複雜的本質講出來,其實密碼學也是能夠理解的。然而,因爲對英國提出的『加密禁令』和澳大利亞提出的『援助與訪問法案』等主題缺少了解而致使的許多全球運動,顯然是弊大於利的作法。git
若是你想要了解密碼學,本文將會以速成課的形式講到你須要知道的幾乎全部知識。下面我將簡要介紹各類加密系統的歷史,並着重講一下密碼學中三種最流行的方向:流密碼、分組密碼以及公鑰密碼系統。算法
密碼是密碼學的基石。密碼就是一組處理信息加密和解密的算法。一個加密算法(E)須要一個密鑰(k)和一段信息(m),就能夠產生一段密文(c)。一樣的,一個解密算法(D)須要一個密鑰(k)和一個以前的密文(c)。能夠表示成下面的形式:編程
這意味着要成爲一個密碼,它必須知足下面的等式才能夠成功解密:瀏覽器
這個等式說明了若是你是用密鑰 K 加密一段信息,那麼你就能夠經過密鑰 K 解密出相同的信息。安全
做爲最古老也最簡單的密碼之一的凱撒密碼,就是用字母表中固定偏移位置的字母替換一段信息中的每個對應的字母的加密方法。服務器
在下面的例子中,信息中的每一個字母就移動了三個字符:網絡
這個密碼能夠用數學方法表示成下面的形式:併發
雖然這種加密方式符合咱們對密碼的定義,可是它一點也不安全。若是一個攻擊者知道使用的是凱撒密碼,那麼他只須要嘗試全部的 25 種組合就能夠破譯這個密碼。即便他不知道使用的是凱撒密碼,他也能夠經過觀察密文中的字母模式來發現使用的就是凱撒密碼。dom
爲了接下來要討論的更安全的加密算法,咱們不得不介紹一種運算:XOR(異或)。函數
XOR 或者說『異或』門是一種布爾數字邏輯門,它接收兩個輸入值 0 或者 1,若是這兩個輸入值不一樣則返回 1,若是相同則返回 0。它能夠用下面的真值表來表示全部輸入輸出的可能:
這個運算經常用符號⊕來表示,就像下面這樣:
0 ⊕ 0 = 0,
0 ⊕ 1 = 1,
1 ⊕ 0 = 1,
1 ⊕ 1 = 0
XOR 有如下幾個重要的性質:
這就意味着 a ⊕ b ⊕ a = b,由於根據上面的性質和法則咱們知道 a ⊕ a ⊕ b 就等於 0 ⊕ b 等於 b。有一點很重要,那就是這個運算只對零和一有效,全部其餘進制的數字必需要先轉換成二進制。
87 ⊕ 73 = 1010111b ⊕ 1001001b = 0011110b = 30
如今咱們能夠開始講咱們第一個安全的密碼了。
根據 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 是 12八、192 或 256 位)。
分組密碼也被稱做密鑰置換或者僞隨機置換,由於它將每個可能的塊都映射到一些其餘的塊上。這個過程是經過密鑰來處理的,密鑰決定了哪個輸入塊映射到哪個相對應的密文塊上面。由於這是一對一的置換,因此若是知道密鑰的話,密文就能夠被解密出來。
第一個廣爲人知的分組密碼是 DES(Data Encryption Standard),它是上世紀 70 年代由 IBM 開發的,而後很快人們就發現了它是不安全的,因而就產生了 3DES,而 3DES 也好景不常,就被替換成了 AES(Advanced Encryption Standard),AES 是在美國國家標準與技術研究院呼籲新標準的分組密碼後於 1997 年開發的。這裏咱們會着重講一下 AES,由於它是如今最經常使用的分組密碼,而 DES 和 3DES 就顯得相形見絀了。
如今讓咱們看一下 AES 是如何工做的。爲了簡單起見,這裏會跳過一些技術細節。若是你想更深刻的瞭解 AES 的相關內容,請查看這篇文章。
AES 和大部分分組密碼同樣都是經過迭代(就是將輸入的文本與一系列密碼反覆的迭代計算)來工做的。第一步就是將密鑰 K(一般來講是 12八、192 或者 256 位,這裏咱們只關注 AES 的 128 位)做爲輸入,而後將它拓展成一系列環形密鑰用來加密咱們的信息。
在這裏,咱們將 128 位(也就是 16 個字節)的輸入密鑰利用例如 Rijndael key schedule 的密鑰拓展算法拓展成 11 個 16 字節的密鑰。而後咱們將每一輪的密鑰 kₙ 和信息 m 做爲輸入,經過函數 R(kₙ, m) 和以前生成的每個密鑰將信息加密 10次。
由於 AES 是 128 位的塊大小,因此咱們能夠將信息 m 用一個 4x4 的字節矩陣來表示。同時咱們也能夠將每一輪的密鑰用 4x4 的矩陣來表示,這樣他們就能夠經過表明消息體的單元格來進行 XOR 運算。
首先,輸入的信息和第一輪密鑰進行 XOR,而後將獲得的結果使用下面幾個函數進行處理:ByteSub
,ShiftRows
以及 MixColumns
(這幾個步驟下面會講到),最後就會獲得最新的消息體。接着咱們使用每一輪的密鑰重複這些步驟 10 次,惟一的區別就是最後一輪不作 MixColumn
處理。最後的消息體再與第 11 輪的密鑰進行 XOR 獲得咱們的結果密文。下面就是以前三個步驟的簡要說明:
ByteSub:消息體矩陣中的每個字節都會用 Substitution Box 中定義的關聯字節來替換。
舉個例子,9a
會替換成 b8
。
ShiftRow:每一行都會移動一個肯定的數量。第一行不移動,第二行向左移動一次,第三行向左移動兩次,第四行向左移動3次。
MixColumns:消息體矩陣的每一列都要進行一個線性變換。
如今咱們終於可使用 AES 來加密數據了。可是你很快就會發現這裏有一個很明顯的限制,就是你不能使用 AES 來一次性加密超過 128 位(16字節)大小的信息。而爲了加密超過 16 字節的信息咱們還須要介紹一個概念:工做模式。
一次性加密超過 128 位的信息有各類各樣的方法(或者說工做模式)。其中最簡單就是著名的電子密碼本,也叫作 ECB。
ECB 是使用分組密碼加密大量數據最簡單的工做模式。它將信息簡單的分紅 16 字節的區塊,而後使用密鑰將這些區塊分別加密。固然了,爲了知足 16 字節的劃分,原文將不得不進行一些填充。舉例來講就是,一個 28 字節的信息須要額外的 4 個字節的填充才能夠分紅兩個 16 字節的區塊。在信息被分割成區塊以後,每個區塊都會使用密鑰分別加密。
雖然這很容易理解,可是也帶來了一個明顯的問題。由於一樣的原文區塊將會生成一樣的密文區塊,這種模式很容易被發現。好比下面使用 ECB 加密的位圖:
相同信息區域加密後仍然是相同的,因此這樣經常使用的模式仍然能夠被分辨出來。爲了消除這個影響,咱們須要使用一種更加安全的工做模式。
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。