返回文章列表

Pycryptodome 資訊加密解密實務應用

本文探討如何使用 Python 的 Pycryptodome 函式庫進行資訊加密與解密,涵蓋對稱加密演算法 AES 和 DES,以及非對稱加密演算法 RSA 的實務應用與程式碼範例。文章詳細說明瞭區塊加密模式、金鑰管理、

資訊安全 Python

Pycryptodome 是 Python 中一個功能強大的密碼學函式庫,提供對稱加密、非對稱加密和雜湊函式等功能,有效保護資料安全。對稱加密使用單一金鑰進行加密和解密,適用於大量資料的快速處理,例如 AES 和 DES 演算法。非對稱加密則使用公鑰和私鑰配對,公鑰加密,私鑰解密,適用於金鑰交換和數位簽章,例如 RSA 演算法。本文將示範如何使用 Pycryptodome 執行 AES、DES 和 RSA 加解密,並說明不同加密模式的特性與應用場景,以及如何安全地管理金鑰。針對檔案加密,文章提供區塊讀取、加密和寫入的完整流程,確保資料處理的效率和安全性。

使用Pycryptodome進行資訊加密與解密

在資訊安全領域,加密技術是保護資料隱私和完整性的重要手段。Python中的Pycryptodome模組提供了多種加密演算法和工具,支援對稱加密、公開金鑰加密和雜湊函式等功能。

對稱加密與公開金鑰加密

對稱加密使用相同的金鑰進行加密和解密,而公開金鑰加密則使用一對金鑰:公鑰用於加密,私鑰用於解密。對稱加密演算法如AES、DES,適合大量資料的快速加密;而公開金鑰演算法如RSA,主要用於金鑰交換和數位簽章。

Pycryptodome簡介

Pycryptodome是一個可靠的密碼學模組,支援區塊加密、串流加密和雜湊計算。它提供了多種加密模式,如GCM、CCM、EAX等,並且支援橢圓曲線密碼學和RSA、DSA金鑰生成。

安裝Pycryptodome

要在Python 3中使用Pycryptodome,需要先安裝相關套件:

$ sudo apt-get install build-essential python3-dev
$ sudo python3 -m pip install pycryptodome

區塊加密

Pycryptodome支援多種區塊加密演算法,包括AES、DES、DES3等。使用這些演算法,需要從Crypto.Cipher套件中匯入相應的模組,並建立一個新的加密物件:

from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_ECB)

其中,key是加密金鑰,MODE_ECB是一種加密模式。

使用DES演算法進行加密和解密

DES是一種區塊加密演算法,要求明文長度是8的倍數。以下是一個使用DES演算法進行加密和解密的範例:

from Crypto.Cipher import DES

# 填補空格直到8個字元
user = "user    ".encode("utf8")
message = "message ".encode("utf8")
key = 'mycipher'

# 建立DES加密物件
cipher = DES.new(key.encode("utf8"), DES.MODE_ECB)

# 加密使用者名稱和訊息
cipher_user = cipher.encrypt(user)
cipher_message = cipher.encrypt(message)

print("Cipher User: " + str(cipher_user))
print("Cipher message: " + str(cipher_message))

# 模擬伺服器端解密
cipher = DES.new(key.encode("utf8"), DES.MODE_ECB)
decipher_user = cipher.decrypt(cipher_user)
decipher_message = cipher.decrypt(cipher_message)

print("Decipher user: " + str(decipher_user.decode()))
print("Decipher Message: " + str(decipher_message.decode()))

內容解密:

  1. 首先,從Crypto.Cipher匯入DES模組,用於建立DES加密物件。
  2. 使用DES.new()方法建立加密物件,需要提供金鑰和加密模式(此例中使用MODE_ECB)。
  3. 對使用者名稱和訊息進行加密,使用encrypt()方法。
  4. 在伺服器端,使用相同的金鑰和加密模式建立新的DES加密物件,並對加密後的資料進行解密,使用decrypt()方法。
  5. 最後,輸出解密後的結果。

雜湊函式

Pycryptodome提供了多種雜湊函式,如MD5、SHA1、SHA256等。可以使用Crypto.Hash子模組來使用這些函式。

使用MD5進行檔案校驗

以下是一個使用MD5雜湊函式計算檔案校驗和的範例:

from Crypto.Hash import MD5

def get_file_checksum(filename):
    hash = MD5.new()
    chunk_size = 8191
    with open(filename, 'rb') as file:
        while True:
            chunk = file.read(chunk_size)
            if len(chunk) == 0:
                break
            hash.update(chunk)
    return hash.hexdigest()

print('The MD5 checksum is', get_file_checksum('checksSumFile.py'))

內容解密:

  1. Crypto.Hash匯入MD5模組,用於建立MD5雜湊物件。
  2. 定義一個函式get_file_checksum(),用於計算檔案的MD5校驗和。
  3. 在函式中,以區塊方式讀取檔案內容,並使用update()方法更新雜湊值。
  4. 最後,使用hexdigest()方法取得十六進位制的校驗和,並輸出結果。

使用Pycryptodome進行資訊加密與解密

AES演算法的加密與解密

進階加密標準(Advanced Encryption Standard, AES)是一種目前廣泛使用的區塊加密演算法。在主要的加密模式中,主要有以下幾種:

  • CBC(Cipher-block chaining)模式:在此模式下,每個明文區塊在加密前會與前一個密鑰區塊進行XOR運算。這樣,每個密鑰區塊都依賴於到目前為止的所有明文。為了使每個訊息都是獨一無二的,通常會使用初始化向量(IV)。
  • ECB(Electronic Code-Book)模式:在此模式下,訊息被分成多個區塊,每個區塊使用相同的金鑰單獨加密。這種方法的缺點是,相同的明文區塊可能會對應到相同的密鑰區塊,從而可以識別出這些模式並發現明文。因此,不建議在應用程式中使用此模式作為加密模式。
  • GCM(Galois/Counter Mode)模式:這是一種用於區塊加密的操作模式,區塊大小為128位元。由於其良好的效能以及能夠利用處理器中的硬體加速功能,AES-GCM已經變得非常流行。此外,透過使用初始化向量,可以隨機化金鑰的生成,從而改善使用相同金鑰加密兩個訊息的過程。

要使用AES加密演算法,需要從Crypto.Cipher.AES子模組中匯入它。由於Pycryptodome的區塊級加密API是非常底層的,它只接受16、24或32位元組長的金鑰,分別對應於AES-128、AES-196和AES-256。金鑰越長,加密越強。

因此,需要確保資料的長度是16位元組的倍數。AES金鑰需要是16、24或32位元組長,而初始化向量需要是16位元組長。這可以使用randomstring模組生成。

from Crypto.Cipher import AES

# 金鑰必須是16、24或32位元組長
key = "secret-key-12345"
encrypt_AES = AES.new(key.encode("utf8"), AES.MODE_CBC, 'This is an IV-12'.encode("utf8"))

# 將使用者輸入填充至32個字元
message = "This is the secret message ".encode("utf8")
ciphertext = encrypt_AES.encrypt(message)
print("密鑰:", ciphertext)

decrypt_AES = AES.new(key.encode("utf8"), AES.MODE_CBC, 'This is an IV-12'.encode("utf8"))
message_decrypted = decrypt_AES.decrypt(ciphertext)
print("解密後的文字:", message_decrypted.strip().decode())

內容解密:

  1. 匯入必要的模組:從Crypto.Cipher匯入AES模組以使用AES加密演算法。
  2. 建立AES物件:使用AES.new()方法建立AES物件,需要提供金鑰、加密模式和初始化向量(IV)。
  3. 加密訊息:使用encrypt()方法對明文訊息進行加密。
  4. 解密訊息:使用decrypt()方法對密鑰進行解密。
  5. 輸出結果:列印出加密後的密鑰和解密後的明文。

為了提高安全性,可以使用Random子模組生成隨機的初始化向量,並使用PBKDF2子模組從密碼生成隨機的金鑰。

from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto import Random

# 金鑰必須是16、24或32位元組長
key = "secret-key-12345"
iterations = 10000
key_size = 16
salt = Random.new().read(key_size)
iv = Random.new().read(AES.block_size)
derived_key = PBKDF2(key, salt, key_size, iterations)

encrypt_AES = AES.new(derived_key, AES.MODE_CBC, iv)
message = "This is the secret message ".encode("utf8")
ciphertext = encrypt_AES.encrypt(message)
print("密鑰:", ciphertext)

decrypt_AES = AES.new(derived_key, AES.MODE_CBC, iv)
message_decrypted = decrypt_AES.decrypt(ciphertext)
print("解密後的文字:", message_decrypted.strip().decode())

內容解密:

  1. 使用PBKDF2生成金鑰:從密碼、鹽值、金鑰大小和迭代次數生成隨機的金鑰。
  2. 生成隨機的初始化向量:使用Random.new().read(AES.block_size)生成隨機的IV。
  3. 加密和解密:使用生成的金鑰和IV進行加密和解密。

使用AES進行檔案加密

AES加密要求每個被寫入的區塊都是16位元組大小的倍數。因此,需要以區塊的形式讀取、加密和寫入資料。區塊大小需要是16的倍數。

def encrypt_file(key, filename):
    chunk_size = 64*1024
    output_filename = filename + '.encrypted'
    iv = Random.new().read(AES.block_size)
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(filename)

    with open(filename, 'rb') as inputfile:
        with open(output_filename, 'wb') as outputfile:
            outputfile.write(struct.pack('<Q', filesize))
            outputfile.write(iv)
            while True:
                chunk = inputfile.read(chunk_size)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += bytes(' ','utf-8') * (16 - len(chunk) % 16)
                outputfile.write(encryptor.encrypt(chunk))

內容解密:

  1. 定義加密函式:建立一個函式來加密檔案,使用AES演算法。
  2. 初始化向量和加密器:生成隨機的IV並建立AES加密器。
  3. 讀取和加密檔案:以區塊的形式讀取檔案,加密後寫入輸出檔案。
def decrypt_file(key, filename):
    chunk_size = 64*1024
    output_filename = os.path.splitext(filename)[0]
    with open(filename, 'rb') as infile:
        origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
        iv = infile.read(16)
        decryptor = AES.new(key, AES.MODE_CBC, iv)
        with open(output_filename, 'wb') as outfile:
            while True:
                chunk = infile.read(chunk_size)
                if len(chunk) == 0:
                    break
                outfile.write(decryptor.decrypt(chunk))
            outfile.truncate(origsize)

內容解密:

  1. 定義解密函式:建立一個函式來解密檔案,使用AES演算法。
  2. 讀取初始化向量和檔案大小:從加密檔案中讀取IV和原始檔案大小。
  3. 解密檔案:以區塊的形式讀取加密檔案,解密後寫入輸出檔案,並截斷到原始大小。

使用pycryptodome進行資料加密與解密

在現代的資訊安全領域中,資料加密已成為保護敏感資訊免受未授權存取的重要手段。Python中的pycryptodome函式庫提供了一系列的加密演算法,包括對稱式加密(如AES)和非對稱式加密(如RSA)。本篇文章將探討如何使用pycryptodome進行檔案的加密和解密。

使用AES演算法進行檔案加密和解密

AES(Advanced Encryption Standard)是一種廣泛使用的對稱式加密演算法。以下是一個使用AES演算法對檔案進行加密和解密的範例:

檔案加密函式

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

def encrypt_file(key, filename):
    chunk_size = 64 * 1024
    output_filename = filename + '.encrypted'
    iv = get_random_bytes(16)
    encryptor = AES.new(key, AES.MODE_CBC, iv)

    with open(filename, 'rb') as infile:
        with open(output_filename, 'wb') as outfile:
            outfile.write(iv)
            while True:
                chunk = infile.read(chunk_size)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += b' ' * (16 - len(chunk) % 16)
                outfile.write(encryptor.encrypt(chunk))

內容解密:

此函式首先開啟原始檔案並讀取其內容,然後使用AES演算法的CBC模式進行加密。初始化向量(IV)被隨機產生並寫入輸出檔案的開頭,以增加加密的安全性。檔案內容被分成多個區塊,每個區塊的大小為chunk_size,並逐一進行加密。

檔案解密函式

def decrypt_file(key, filename):
    chunk_size = 64 * 1024
    output_filename = filename[:-9]  # 去除'.encrypted'副檔名

    with open(filename, 'rb') as infile:
        iv = infile.read(16)
        decryptor = AES.new(key, AES.MODE_CBC, iv)
        with open(output_filename, 'wb') as outfile:
            while True:
                chunk = infile.read(chunk_size)
                if len(chunk) == 0:
                    break
                outfile.write(decryptor.decrypt(chunk))

內容解密:

此函式讀取加密檔案的內容,首先提取出初始化向量(IV),然後使用AES演算法的CBC模式進行解密。解密後的內容被寫入輸出檔案。

主函式:提供使用者加密或解密檔案的選項

def main():
    choice = input("您想要(E)加密還是(D)解密?: ")
    if choice == 'E':
        filename = input('要加密的檔案: ')
        password = input('密碼: ')
        encrypt_file(getKey(password.encode("utf8")), filename)
        print('完成.')
    elif choice == 'D':
        filename = input('要解密的檔案: ')
        password = input('密碼: ')
        decrypt_file(getKey(password.encode("utf8")), filename)
        print('完成.')
    else:
        print('未選擇任何選項.')

if __name__ == "__main__":
    main()

內容解密:

此主函式提供了一個簡單的使用者介面,讓使用者可以選擇對檔案進行加密或解密。根據使用者的選擇,呼叫相應的加密或解密函式。

使用RSA演算法進行資料加密和解密

RSA是一種非對稱式加密演算法,使用公鑰和私鑰進行加密和解密。以下是一個使用RSA演算法進行資料加密和解密的範例:

金鑰產生函式

from Crypto.PublicKey import RSA

def generate(bit_size):
    keys = RSA.generate(bit_size)
    return keys

內容解密:

此函式使用RSA演算法產生一對公鑰和私鑰。

加密和解密函式

from Crypto.Cipher import PKCS1_OAEP

def encrypt(pub_key, data):
    cipher = PKCS1_OAEP.new(pub_key)
    return cipher.encrypt(data)

def decrypt(priv_key, data):
    cipher = PKCS1_OAEP.new(priv_key)
    return cipher.decrypt(data)

內容解密:

這些函式使用RSA演算法的PKCS1_OAEP模式進行資料的加密和解密。