天天看點

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

一、對稱加密

對稱加密:需要對加密和解密使用相同密鑰的加密算法。

優點:速度快,适合加密大量資料時使用。

缺點:不利于傳送密鑰。(後面文章在介紹非對稱加密傳輸對稱加密的密鑰,此處應用是檔案加密,密鑰隻有自己知道)

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

對稱加密的本質是密鑰與明文進行異或運算,是以速度非常快,某些情況下還可以進行并行加密(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模式是将整個明文分成若幹段相同的小段,然後對每一小段進行加密。

解密過程直接将圖中原文與密文位置互換即可

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

1.2 CBC 模式

CBC模式是先将明文切分成若幹小段,然後每一小段與初始塊或者上一段的密文段進行異或運算後,再與密鑰進行加密。

解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,再用同樣的算法與密鑰進行解密。

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

1.3 CFB模式

CFB模式是先将明文切分成若幹小段,對上一個密文進行加密處理(第一次就用初始畫向量),然後與明文塊進行異或,得到新的密文,再重複上述操作

解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,注意,解密的過程同加密,第一步仍然是對初始化向量IV進行加密,然後與密文1進行異或,得到明文1,之後的過程同樣操作,直到最後一個解密完成

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

1.4 OFB模式

OFB模式是先将明文切分成若幹小段,不斷的對初始化向量進行加密,将加密的結果與明文進行異或,最終得到密文。

解密過程直接将圖中向 “下” 的箭頭反過來變成向上的,注意,解密的過程同加密,第一步仍然是對初始化向量IV進行加密,然後與密文1進行異或,得到明文1,之後的過程同樣操作,直到最後一個解密完成(文字同CFB)

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

1.5 CFB 模式與 OFB 模式對比

上面講的 CFB 與 OFB,在同片與文字上有相近的地方,将不同點進行局部放大,觀察 CFB 與 OFB 的差異,有助于對這兩個加密模式的了解,總的來說,OFB 就是不斷對初始化向量進行加密,再與明文異或,CFB是不斷的對密文進行加密,在與新的明文異或。

詳解AES對稱加密(python實作檔案加密)一、對稱加密二、Python 密碼庫——Cryptodome三、用python實作檔案加密

二、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 加解密失敗,解密資料與中繼資料不相等')