Python, PyCryptodome und AES-Verschlüsselung

Dieser Blogbeitrag beschäftigt sich mit der Verschlüsselung von Textdateien. Zum Einsatz kommen dabei die Programmiersprache Python zusammen mit dem Python-Paket PyCryptodome, einem Fork des Pakets PyCrypto. Bei PyCryptodome handelt es sich um ein OpenSource-Projekt. Der Code kann auf Github eingesehen und geklont werden.

git clone https://github.com/Legrandin/pycryptodome.git

Die Bibliothek pycryptodome wird mit pip oder pip3 zu einem Projekt hinzugefügt. Es ist sinnvoll, zuvor eine virtuelle Umgebung zu erstellen.

pip install pycryptodome

In diesem Tutorial soll eine symmetrische Verschlüsselung verwendet werden. Zum Einsatz kommt das wohl am bedeutendste symmetrische Verschlüsselungsverfahren, der Advanced Encryption Standard (AES). Dabei wird für die Verschlüsselung ein Passwort verwendet. Mit demselben Passwort kann die verschlüsselte Datei wieder entschlüsselt werden. Im folgenden Beispiel wird die AES-256-Verschlüsselung im CFB-Modus genutzt. Wie die Zahl „256“ vermuten lässt, wird eine Schlüssellänge von 256 Bit (=32 Byte 32 Byte) verwendet (daher im Code auch die Angabe von dkLen=32).

PyCryptodome muss zunächst importiert werden. Außerdem wird Path aus dem Paket pathlib verwendet:

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

from pathlib import Path

In diesem Beispiel sind der Pfad zu der zu verschlüsselnden Textdatei und das Passwort im Code hinterlegt.

file = Path.home() / "Desktop" / "Text.txt"
password = "my_secret_password"

Die Datei „Text.txt“ wird mit with open() gelesen:

with open(file, "rb") as f:
    data = f.read()

Dann erfolgt die Verschlüsselung:

salt = get_random_bytes(16)
iv = get_random_bytes(16)
key = PBKDF2(password, salt, dkLen=32)
cipher = AES.new(key, AES.MODE_CFB, iv=iv)
encrypted_data = salt + iv + cipher.encrypt(data)

AES im CFB-Modus erfordert einen Initialization Vector (iv). Damit wird sichergestellt, dass beim Verschlüsseln identischer Daten mit demselben Schlüssel unterschiedlicher Ciphertext generiert wird.

Der für die Verschlüsselung verwendete Schlüssel (key) wird mit PBKDF2 erzeugt. Es handelt sich dabei um eine Schlüsselableitungsfunktion. Sie macht aus einem Passwort (hier: my_secret_password) einen kryptographisch sicheren Schlüssel, wobei zusätzlich salt hinzugefügt wird. Es handelt sich dabei um eine zufällige Bytefolge (hier: 16 Bytes), die beim Ableiten des Schlüssels aus dem Passwort mit einfließt. Dies hat zur Folge, dass bei der Verwendung desselben Passworts jedes Mal ein anderer Schlüssel generiert wird.

Im nächsten Schritt wird zur verschlüsselten Datei die Endung „.enc“ hinzugefügt, damit sie besser zu identifizieren ist:

enc_file_path = file.with_suffix(file.suffix + ".enc")

Zum Schluss kann die verschlüsselte Datei mit with open() gespeichert werden:

with open(enc_file_path, "wb") as f:
    f.write(encrypted_data)
    print(f"File encrypted: {enc_file_path}")

Der Code ließe sich noch an vielen Stellen verbessern. So könnte man mit input() den Nutzer nach der zu verschlüsselnden Datei und nach dem Passwort fragen. Außerdem macht es Sinn, etwaige Ausnahmebehandlungen hinzuzufügen, z.B. um zu überprüfen, ob der angegeben Pfad tatsächlich existiert.

Weiterführende Links