一 對稱密碼

一次性密碼本

一次性密碼本是一種非常簡單,它的原理是“將明文與一串隨機的比特序列進行XOR運算”。如果將硬幣的證明設爲0,反面設爲1,則通過不斷擲硬幣就能產生這樣一串隨機的比特序列。

加密

解密


正如上面所講到的那樣,一次性密碼本是一種非常簡單的密碼,如此簡單的密碼居然無法破譯,這真是讓人匪夷所思。這裏說的無法破譯,並不是指在現實的時間內難以破譯,而是指即便擁有一種運算能力無窮大的計算機,可以在一瞬間遍歷任意大小的密鑰空間,也依然無法破解。
  我們假設對一次性密碼本的密文進行嘗試進行暴力破解,那麼總有一天我們會嘗試到和加密時相同的密鑰,也就能解密出明文midnight,這是毋庸置疑的事實,然而,即便我們解密出midnight這個字符串,我們也無法判斷它是否是正確的明文。
這是因爲在對一次性密碼本嘗試解密的過程中,所有的64比特的排列組合都會出現,這其中包含像aaaaaaaa,ZZZZZZZZ這樣的規則字符串,也會包含midnight,onenight等英文單詞,還會包含其他看不懂的組合,所以,我們無法判斷出其中哪一個纔是正確的明文。
 所謂玻璃破解,就是按順序將所有的密鑰都嘗試一遍,並判斷得到的是不是正確的明文的方法。然後在一次性密碼本中,由於我們無法判斷得到明文是不是正確的明文,因此一次性密碼本是無法破譯的。

爲什麼沒有被普遍使用

密鑰配送

最大的問題在於密鑰的配送。
我們來設想一下使用一次性密碼本進行通信的場景,發送者Alice使用一次性密碼本生成密文發送出去。發送的密文即便被竊聽者Eve截獲也沒關係,因爲一次性密碼本是絕對無法破譯的。
接收者Bob收到了Alice發來的密文。Bob要想進行節目,就必須使用和Alice進行加密時相同的密鑰,因此Alice必須將密鑰發送給Bob,且該密鑰的長度和密文是相等的。但這樣就產生了一個矛盾,如果能夠有一種方法將密鑰安全送出去,那麼豈不是也可以用同樣的方法來安全地發送明文了麼?

密鑰保存

一次性密文本中,密鑰的長度必須和明文的長度相等,而且由於密鑰保護着明文的機密性,因此必須妥善保存,不能被竊聽者竊取。不過,如果能夠有辦法安全保護與明文一樣長的密鑰,那豈不是就有辦法安全保存明文本身了麼?

密鑰的重用

在一次性密碼本中絕對補鞥呢用重用過去用過的隨機比特序列,一次性密碼本中的“一次性”由此而來。這是因爲作爲密鑰的比特序列一旦泄露,過去所有的機密通信內容將全部被解密。

密鑰的同步

一次性密碼本中還會產生髮送者與接收者之間的密鑰同步問題。當明文很長時,一次性密碼本的密鑰也會跟着變長。如果明文是一個大小爲100MB的文件,則密鑰的大小也一定是100MB。而且在通信過程中,發送者和接收者的密鑰的比特序列不允許有任何錯位,否則錯位後的所有信息都無法解密。

密鑰的生成

一次性密碼本中,需要生成大量的隨機數。這裏的隨機數並不是通過計算機程序生成的僞隨機數,而必須是無重現性的真正隨機數。
綜上所述,一次性密碼本是一種幾乎沒有實用的密碼。但是,一次性密碼本的思路卻孕育出了流密碼 。流密碼使用的不是真正的隨機比特序列,而是僞隨機數生成器產生的比特序列。流密碼雖然不是無法破譯的,但只要使用高性能的僞隨機數生成器,就能夠構建出較高強度的密碼系統,後續會繼續介紹。

DES

DES的密文可以在短時間內被破譯,因此除了用它來解密一起的密文以外,現在我們不應該再使用DES了。

加密和解密

DES是一種將64比特的明文加密成64比特的密文的對稱密碼算法,它的密鑰的長度是56比特。儘管從規格上來說,DES的密鑰長度是64比特,但由於每隔7比特會設置一個用於錯誤檢查的比特,因此實質上其密鑰長度是56比特。
DES 是以64比特的明文(比特序列)爲一個單位來進行加密的,這個64比特的單位稱爲分組 ,一般來說,以分組爲單位進行處理的密碼算法稱爲分組密碼,DES就是分組密碼的一種。
DES每次只能加密64比特的數據,如果要加密的明文比較長,就需要對DES加密進行迭代(反覆),而迭代的具體方式就稱爲模式。

DES的結構(Feistel網絡)

DES的基本結構是由Horst Feistel設計的,因此也稱爲Feistel網絡(Feistel network)、Feistel結構(Feistel structure)或者Feistel密碼(Feistel cipher)。這一結構不僅被用於DES,在其他很多密碼算法中也有應用。
Feistel網絡中,加密的各個步驟稱爲輪,整個加密過程就是進行若干次輪的循環,下圖,展現的是Feistel網絡中一輪的計算流程。DES是一種16輪循環的Feistel網絡。

上圖兩個方框表示Feistel網絡中的一輪的輸入(明文)。輸入的數據被等分爲左右兩半分別進行處理。在圖中,左半部分寫作“左側”,右半部分寫作“右側”。
下圖的兩個方框表示本輪的輸出(密文)。輸出的左半部分寫作“加密後的左側”,右半部分寫作“右側”。
中間的“子密鑰”指的是本輪加密所使用的的密鑰,在Feistel網絡中,每一輪都需要使用一個不同的子密鑰。由於密鑰只在一輪中使用,它只是一個局部的密鑰,因此才稱爲子密鑰(subkey)
輪函數的作用是根據“右側”和子密鑰生成對“左側”進行加密的比特序列,它是密碼系統核心。將輪函數的輸出與“左側”進行XOR運算,其結果就是“加密後的左側”。也就是說,我們用XOR將輪函數的輸出與“左側”進行合併。而輸入的“右側”則會直接成爲輸出的“右側”。
總結一下,一輪的具體計算步驟如下:

  1. 將輸入的數據等分爲左右兩個部分
  2. 將輸入的右側直接發送到輸出的右側
  3. 將輸入的右側發送到輪函數
  4. 輪函數根據右側數據和子密鑰,計算出一串看上去是隨機的比特序列
  5. 將上一步得到的比特序列與左側序列進行XOR運算,並將結果作爲加密後的左側。

但是,這樣看來,“右側”根本沒有加密,因此我們需要用不同的子密鑰對一輪的處理重複若干次,並在沒兩輪處理指間將左側和有責的數據對調。

上圖展現了一個3輪的Feistel網絡,3輪加密計算需要進行兩次左右對調。對調只在兩輪指間進行,租後一輪結束不需要對調。
那麼,Feistel網絡如何解密呢?

如上圖所示,通過上述操作都能夠將密文正確的還原明文。

有多輪的情況也是一樣的,也就是說,Feistel網絡的解密操作,只要按照相反的順序來使用子密鑰就可以完成了,而Feistel網絡本身的結構,在加密和解密都是完全相同的。

Feistel網絡性質

  • Feistel網絡,輪數可以任意增加。無論運行多少輪的加密計算,都不會發生無法解密的情況
  • Feistel網絡,加密時無論使用任何函數作爲輪函數都可以正確解密。
  • Feistel網絡,加密和解密可以用完全相同的結構來實現,這也是Feistel網絡的一個特點。

三重DES

現在DES已經可以在現實的時間內被暴力破解,因此我們需要一種替代DES的分組密碼,三重DES就是出於這個目的被開發出來的。
三重DES是爲了增加DES的強度,將DES重複3次所得到的一種密碼算法,也稱爲TDEA(Triple Date Encryption Algorithm),通常縮寫爲3DES。

三重DES的加密


明文經過三次DES處理才能變成最後的密文,由於DES密鑰的長度實質上是56比特,因此三重DES密鑰的長度就是168比特。
三重DES並不是進行三次DES加密,而是加密->解密->加密的過程。在加密算法中加入解密操作,讓人感覺很不可思議實際上,這個算法是IBM公司設計出來的,目的是爲了讓三重DES能夠兼容普通的DES。

三重DES的解密

三重DES的解密過程和加密過程正好相反,是以密鑰3,密鑰2,密鑰1的順序執行解密->加密->解密的操作。

AES

AES(Advanced Encryption Standard)是取代前任標準DES而成爲新標準的一種對稱密碼算法。全世界的企業和密碼學家提交了多個對稱密碼算法作爲AES候選,最終在2000年的時候,從這些候選算法中選出了有一種名爲Rijndael的對稱密碼算法,並將其確定爲AES。

Rijndael

Rijndael是由比利時密碼學家Joan Daemen 和Vincent Rijmen設計分組密碼算法,於2000年被選爲新一代的標準算法密碼-AES。
Rijindael的分組長度和密鑰長度可以分別爲32比特爲單位,在128比特到256比特的範圍內進行選擇。不過AES規格中,分組長度固定爲128比特,密鑰長度只有128、192和256比特三種。

Rijndael加密和解密

和DES一樣,Rijndael算法也是由多個輪構成,其中每一個輪分爲SubBytes、ShiftRows、MixColumns和AddRoundKey共4個步驟。DES使用Feistel網絡作爲基本結構,而Rijndael沒有使用Feistel網路,而是使用了SPN網路。
Rijndael的輸入分組128比特,也就是16個字節。首先,需要逐個字節地對16字節地輸入數據進行SubBytes處理。所謂SubBytes,就是以每個字節地值(0~255的任意值)爲索引,從一張表擁有256個值替換表(S-Box)中查找出對應的值來處理。也就是說,要將一個1字節地值替換成另一個1字節地值。這個步驟用語言來描述比較麻煩,大家可以將它想象成爲前面介紹的簡單替換密碼的256個字母的版本。

SubBytes之後需要進行ShiftRows處理。這一步是將以4字節爲單位的行,按照一定的規則向左平移,且每一行平移的字節數是不同的。

ShiftRows之後需要進行MixColumns處理。這一步是對一個4字節地值進行比特運算,將其變爲另外一個4個字節值。

最後,需要將MixColumns的輸出與輪密鑰進行XOR,即進行AddRoundKey處理。到這裏Rijndael的一輪就接收了。實際上,在Rijndael中需要重複進行10~14輪計算。

通過上面的結構,我們可以發現輸入比特在一輪中都會被加密。和每一輪都只加密一般輸入的比特的Feistel網絡相比,這種方式的優勢在於加密所需要的輪數更少。此外,這種方式還有一個優勢,即SubBytes、ShiftRows、MixColumns可以分別以字節、行、列爲單位進行並行計算。

在加密過程中,每一輪所進行的處理爲:
SubBytes——>ShiftRows——>MixColumns——>AddRoundKey
而在解密時,則是相反的順序來進行的,即
AddRoundKey——>MixColumns——>ShiftRows——>SubBytes

其中,AddRoundKey是與輪密鑰進行XOR運算,因此這一步在加密和解密是是完全相同的。


Rijndael的破譯

對於Rijndael來說,可能會出現以前不存在的新的攻擊方式。Rijndael的算法背後有這嚴謹的數學結構,也就是說從明文到密文的計算過程可以全部用公司來表達,這是在以前任何密碼算法都不具備的性質。如果Rijndael的公司能夠通過數學運算求解,哪也就是意味着Rijndael能夠通過數學方法進行POI,而這也就爲新的攻擊方式的產生提供了可能。

補充

AES相比同類對稱加密算法速度算是非常快,比如在有AES-NI的x86服務器至少能達到幾百M/s的速度。安全性在可預見的未來是基本等同的,因爲即使是128位也足夠複雜無法被暴力破解。現在112位密碼還在商業應用,而128位是112位的幾萬倍,所以在實務中用128位比較划算(稍節約資源)。
AES256比128大概需要多花40%的時間,用於多出的4輪round key生成以及對應的SPN操作。另外,產生256-bit的密鑰可能也需要比128位密鑰多些開銷,不過這部分開銷應該可以忽略。安全程度自然是256比128安全,因爲目前除了暴力破解,並沒有十分有效的代數攻擊方法。
AES128和AES256主要區別是密鑰長度不同(分別是128bits,256bits)、加密處理輪數不同(分別是10輪,14輪),後者強度高於前者。當前AES是較爲安全的公認的對稱加密算法。
關於用AES128還是AES256算法,個人認爲AES128已經足夠用,當然AES256可以作爲一個營銷手段使用。

應該使用哪種對稱密碼呢

首先,DES不應再應用任何新的用途。其次,我們也沒有理由將三重DES用於任何新的用途。一般來說,我們不應該使用任何自制的密碼算法,而是應該使用AES。因爲其在選定的過程中,經過了全世界密碼學家所進行的高品質的驗證工作,而對於自制的密碼算法則很難進行這樣的驗證。

參考資料

該系列的主要內容來自《圖解密碼技術第三版》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章