標籤:流行 ret 最簡 反饋 大於 實現 函數 返回 隨機
通常,大多數的區塊編碼器演算法都是把資料按照64位分組的方式進行加密和解密。但是幾乎所有的加密工作所涉及的資料量都遠遠大於64位,因此就需要不斷地重複加密過程,直到處理完所有的分組。這種區塊編碼器中所涉及的重複性方式稱為區塊編碼器模式。
處理多個資料分組最簡單的方式是將每一個產生的密文分組添加到之前產生的密文分組之後。這種簡單的方式被稱為ECB,或者電子碼本(electronic code book)。這種方法的簡單性使其比較流行,但它相對來說是不安全的。主要問題是,對於任意給定的密鑰,相同的明文區塊編碼器之後得到的密文結果總是一樣的,即明文和密文的分組是一一對應的關係。假如駭客破解了哪怕一小段資料,他就可以以此建立一個密碼本,來對其他資料區段進行破解。
一種更好的方法是CBC或被稱為密碼分組連結的模式。
CBC模式通過對分組密碼增加簡單的操作和反饋避免ECB中出現的問題。反饋使得密文的每個分組都同之前執行的操作在一定程度上有依賴關係(ECB中每個分組的加密和解密都是獨立的)。在CBC模式中,用之前的密文分組作為反饋,這樣就算是明文中的同一個分組,每次都好像加密成另一個不同的密文分組一樣。
對於之前作為反饋的密文分組,在加密一個明文分組前,將前一個輸出的密文分組與該明文分組求異或,然後再加密。
當解密時,將前一個輸出的明文分組同接下來待解密的密文分組求異或,然後再解密。這兩種方式可以簡單的表示為:
Ci = Ek(Pi ⊕ Ci-1)
Pi = Ci-1 ⊕ Dk(Ci)
這裡Ci和Pi為緩衝區C和P中的第(i)個密文和明文分組,而Ek和Dk是使用密鑰K進行的加密和解密操作。
通常,會在明文的開始處增加一個隨機的資料區塊。這是因為即使有駭客知道明文的第一個分組包含的資訊,它也不能用於類比連結的順序。這個增加的隨機資料區塊稱為 初始向量。按照正常的方式對其加密,這裡不需要任何反饋。然後,將加密後的初始向量作為接下來加密和解密第一個分組資料的反饋。
下面的樣本中給出了兩個函數(cbc_encipher和cbc_decipher)的實現。它們採用DES演算法中的CBC模式來對緩衝區中的資料做加密和解密的動作。
函數cbc_encipher接受一個size位元組大小的明文緩衝區作為參數,使用key作為密鑰來對其加密。該函數假設明文的第一個分組是64位的初始向量。
函數cbc_decipher接受一個size位元組大小的密文緩衝區作為參數,使用key作為密鑰來對期解密。為了保持對稱性,初始化向量也要解密,並作為明文的第一個分組返回。
兩個函數的時間複雜度都是O(n),這裡n代表加密或解密的分組數量。這是因為這兩個函數都只是簡單地調用複雜度同為O(1)的des_encipher和dex_decipher,每處理一個分組調用一次。
樣本:DES演算法的CBC模式實現
/*cbc.c*/#include <stdlib.h>#include "bit.h"#include "cbc.h"#include "encipher.h"/*cbc_encipher DES演算法中的cbc加密模式*/void cbc_encipher(const unsigned char *plaintext, unsigned char *ciphertext, const unsigned char *key, int size){ unsigned char temp[8]; int i; /*加密初始化向量*/ des_encipher(&plaintext[0],&ciphertext[0],key); /*使用DES演算法中的CBC模式加密緩衝區*/ i=8; while(i < size) { bit_xor(&plaintext[i], &ciphertext[i-8], temp, 64); /*temp = Pi XOR Ci-1*/ des_encipher(temp,&ciphertext[i],NULL); /*Ek(temp)*/ i=i+8; } return;}/*cbc_descipher DES演算法中的cbc解密模式*/void cbc_decipher(const unsigned char *ciphertext, unsigned char *plaintext, const unsigned char *key, int size){ unsigned char temp[8]; int i; /*解密初始化向量*/ des_decipher(&ciphertext[0], &plaintext[0], key); /*使用DES演算法中的CBC模式解密緩衝區*/ i=8; while(i < size) { des_decipher(&ciphertext[i],temp,NULL); /*temp = Dk(Ci)*/ bit_xor(&ciphertext[i-8], temp, &plaintext[i], 64); /*Ci-1 XOR temp*/ i=i+8; } return;}
DES密碼編譯演算法應用:區塊編碼器模式