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()))
內容解密:
- 首先,從
Crypto.Cipher匯入DES模組,用於建立DES加密物件。 - 使用
DES.new()方法建立加密物件,需要提供金鑰和加密模式(此例中使用MODE_ECB)。 - 對使用者名稱和訊息進行加密,使用
encrypt()方法。 - 在伺服器端,使用相同的金鑰和加密模式建立新的DES加密物件,並對加密後的資料進行解密,使用
decrypt()方法。 - 最後,輸出解密後的結果。
雜湊函式
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'))
內容解密:
- 從
Crypto.Hash匯入MD5模組,用於建立MD5雜湊物件。 - 定義一個函式
get_file_checksum(),用於計算檔案的MD5校驗和。 - 在函式中,以區塊方式讀取檔案內容,並使用
update()方法更新雜湊值。 - 最後,使用
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位元組長。這可以使用random和string模組生成。
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())
內容解密:
- 匯入必要的模組:從
Crypto.Cipher匯入AES模組以使用AES加密演算法。 - 建立AES物件:使用
AES.new()方法建立AES物件,需要提供金鑰、加密模式和初始化向量(IV)。 - 加密訊息:使用
encrypt()方法對明文訊息進行加密。 - 解密訊息:使用
decrypt()方法對密鑰進行解密。 - 輸出結果:列印出加密後的密鑰和解密後的明文。
為了提高安全性,可以使用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())
內容解密:
- 使用PBKDF2生成金鑰:從密碼、鹽值、金鑰大小和迭代次數生成隨機的金鑰。
- 生成隨機的初始化向量:使用
Random.new().read(AES.block_size)生成隨機的IV。 - 加密和解密:使用生成的金鑰和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))
內容解密:
- 定義加密函式:建立一個函式來加密檔案,使用AES演算法。
- 初始化向量和加密器:生成隨機的IV並建立AES加密器。
- 讀取和加密檔案:以區塊的形式讀取檔案,加密後寫入輸出檔案。
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)
內容解密:
- 定義解密函式:建立一個函式來解密檔案,使用AES演算法。
- 讀取初始化向量和檔案大小:從加密檔案中讀取IV和原始檔案大小。
- 解密檔案:以區塊的形式讀取加密檔案,解密後寫入輸出檔案,並截斷到原始大小。
使用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模式進行資料的加密和解密。