一、對稱加密
對稱加密:需要對加密和解密使用相同密鑰的加密算法。
優點:速度快,适合加密大量資料時使用。
缺點:不利于傳送密鑰。(後面文章在介紹非對稱加密傳輸對稱加密的密鑰,此處應用是檔案加密,密鑰隻有自己知道)
對稱加密的本質是密鑰與明文進行異或運算,是以速度非常快,某些情況下還可以進行并行加密(OFB模式)
對稱加密有五種模式,分别是:
1.電碼本模式(Electronic Codebook Book (ECB))
2.密碼分組連結模式(Cipher Block Chaining (CBC))
3.密碼回報模式(Cipher FeedBack (CFB))
4.輸出回報模式(Output FeedBack (OFB))
5.電腦模式(Counter (CTR))(不常見,不做介紹)
1.1 ECB模式
ECB模式是将整個明文分成若幹段相同的小段,然後對每一小段進行加密。
解密過程直接将圖中原文與密文位置互換即可
1.2 CBC 模式
CBC模式是先将明文切分成若幹小段,然後每一小段與初始塊或者上一段的密文段進行異或運算後,再與密鑰進行加密。
解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,再用同樣的算法與密鑰進行解密。
1.3 CFB模式
CFB模式是先将明文切分成若幹小段,對上一個密文進行加密處理(第一次就用初始畫向量),然後與明文塊進行異或,得到新的密文,再重複上述操作
解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,注意,解密的過程同加密,第一步仍然是對初始化向量IV進行加密,然後與密文1進行異或,得到明文1,之後的過程同樣操作,直到最後一個解密完成
1.4 OFB模式
OFB模式是先将明文切分成若幹小段,不斷的對初始化向量進行加密,将加密的結果與明文進行異或,最終得到密文。
解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,注意,解密的過程同加密,第一步仍然是對初始化向量IV進行加密,然後與密文1進行異或,得到明文1,之後的過程同樣操作,直到最後一個解密完成(文字同CFB)
1.5 CFB 模式與 OFB 模式對比
上面講的 CFB 與 OFB,在同片與文字上有相近的地方,将不同點進行局部放大,觀察 CFB 與 OFB 的差異,有助于對這兩個加密模式的了解,總的來說,OFB 就是不斷對初始化向量進行加密,再與明文異或,CFB是不斷的對密文進行加密,在與新的明文異或。
二、Python 密碼庫——Cryptodome
後續再補充
三、用python實作檔案加密
from Cryptodome.Cipher import AES
import operator # 導入 operator,用于比較原始資料與加解密後的資料
AES_BLOCK_SIZE = AES.block_size # AES 加密資料塊大小, 隻能是16
AES_KEY_SIZE = 16 # AES 密鑰長度(機關位元組),可選 16、24、32,對應 128、192、256 位密鑰
key = "ok let's go" # AES 加解密密鑰
# 待加密文本補齊到 block size 的整數倍
def PadTest(bytes):
while len(bytes) % AES_BLOCK_SIZE != 0: # 循環直到補齊 AES_BLOCK_SIZE 的倍數
bytes += ' '.encode() # 通過補空格(不影響源檔案的可讀)來補齊
return bytes # 傳回補齊後的位元組清單
# 待加密的密鑰補齊到對應的位數
def PadKey(key):
if len(key) > AES_KEY_SIZE: # 如果密鑰長度超過 AES_KEY_SIZE
return key[:AES_KEY_SIZE] # 截取前面部分作為密鑰并傳回
while len(key) % AES_KEY_SIZE != 0: # 不到 AES_KEY_SIZE 長度則補齊
key += ' '.encode() # 補齊的字元可用任意字元代替
return key # 傳回補齊後的密鑰
# AES 加密
def EnCrypt(key, bytes):
myCipher = AES.new(key, AES.MODE_ECB) # 建立一個 AES 算法執行個體,使用 ECB(電子密碼本)模式
encryptData = myCipher.encrypt(bytes) # 調用加密方法,得到加密後的資料
return encryptData # 傳回加密資料
# AES 解密
def DeCrypt(key, encryptData):
myCipher = AES.new(key, AES.MODE_ECB) # 建立一個 AES 算法執行個體,使用 ECB(電子密碼本)模式
bytes = myCipher.decrypt(encryptData) # 調用解密方法,得到解密後的資料
return bytes # 傳回解密資料
# 主函數,從這裡開始執行
if __name__ == '__main__':
with open('testfile/source.c', 'rb') as f: # 以二進制模式打開檔案
bytes = f.read() # 将檔案内容讀取出來到位元組清單中
print('源檔案長度:{}'.format(len(bytes)))
key = PadKey(key.encode()) # 将密鑰轉換位位元組清單并補齊密鑰
bytes = PadTest(bytes) # 補齊原始資料
print('補齊後的源檔案長度:{}'.format(len(bytes)))
encryptTest = EnCrypt(key, bytes) # 利用密鑰對原始資料進行加密
decryptTest = DeCrypt(key, encryptTest) # 利用密鑰對加密的資料進行解密
if operator.eq(bytes, decryptTest) == True: # 檢查加解密是否成功
print('AES 加解密成功!')
else:
print('AES 加解密失敗,解密資料與中繼資料不相等')