Skip to main content

Dateiverschlüsselung in Python: Ein umfassender Überblick über symmetrische und asymmetrische Verfahren

Artikel von

Keshav Malik

feature python encryption

22. November 2023

0 Min. Lesezeit

In unserer modernen Welt teilen wir ständig private, vertrauliche und sensible Informationen über digitale Kanäle. Ein grundlegender Bestandteil dieser Kommunikation ist die Dateiverschlüsselung – dabei werden Daten mithilfe von Verschlüsselungsalgorithmen in ein unlesbares Format umgewandelt.

Es gibt zwei Hauptarten der Verschlüsselung: symmetrische und asymmetrische. Symmetrische Verschlüsselung ist wie eine verschließbare Box mit nur einem Schlüssel. Haben zwei Personen den Schlüssel, können sie die Box hin- und herreichen und sicher sein, dass nur sie sie öffnen können. Asymmetrische Verschlüsselung verwendet dagegen ein Schlüsselpaar. Stellen Sie sich eine Box vor, die Sie mit einem Schlüssel verschließen, aber nur mit einem zweiten Schlüssel öffnen können. Den Schlüssel zum Verschließen (den öffentlichen Schlüssel) können Sie gefahrlos weitergeben, denn niemand kann die Box öffnen (die Daten entschlüsseln), ohne den Schlüssel zum Öffnen (den privaten Schlüssel).

Dieser Artikel bietet einen Einblick in die Verschlüsselung mit Python. Bei der symmetrischen Verschlüsselung konzentrieren wir uns auf den Key Management Service (KMS) von Amazon und PyNaCl SecretBox. Anschließend sehen wir uns die asymmetrische Verschlüsselung und die Public/Private Box von PyNaCl an.

Voraussetzungen

Für dieses Tutorial benötigen Sie:

  • Python installiert (v3.7 oder höher)

  • pipenv installiert. Dieser Python-Abhängigkeitsmanager hilft Ihnen, Konflikte zwischen Paketversionen zu vermeiden. Installieren Sie ihn mit pip install pipenv.

  • Installation der erforderlichen Pakete (aws-encryption-sdk, PyNaCl und cryptography) mit dem Befehl pipenv install aws-encryption-sdk pynacl cryptography. 

  • Ein funktionierendes AWS-Konto und ein KMS-Schlüssel (halten Sie die Schlüssel-ID und die AWS-Region bereit – wir benötigen sie beim Aufruf des Python-Programms).

  • Das AWS-Befehlszeilentool (awscli) installiert. Führen Sie aws configure aus, um AWS auf Ihrem Computer einzurichten. 

  • Ein neues Projekt, das in einer isolierten Umgebung eingerichtet und wie folgt erstellt wurde:

mkdir python_encryption && cd python_encryption
pipenv shell

Den fertigen Code finden Sie im vollständigen Projektcode.

Symmetrische Verschlüsselung in Python

Bei der symmetrischen Verschlüsselung wird derselbe Schlüssel zum Ver- und Entschlüsseln von Daten verwendet. Sie ist einfach, schnell und effizient und eignet sich ideal zum Schutz großer Datenmengen.

In diesem Tutorial verwenden wir Amazon KMS und PyNaCl SecretBox, um symmetrische Verschlüsselung in Python umzusetzen. Amazon KMS hilft uns dabei, Verschlüsselungsschlüssel in der Amazon-Web-Services-(AWS-)Cloud zu erstellen, zu kontrollieren und zu verwalten. Sie können sich den Dienst als Schlüsselbund in der Cloud mit einer zusätzlichen Sicherheitsebene vorstellen. SecretBox ist eine Python-Bibliothek, die Verschlüsselung einfach und zugänglich macht. Stellen Sie sie sich als Ihren persönlichen Tresor vor.

Symmetrische Verschlüsselung mit Amazon KMS und Verschlüsselungs-SDKs

Amazon KMS ist ein cloudbasierter Dienst zur Verwaltung kryptografischer Schlüssel. Er lässt sich nahtlos in andere AWS-Services und Software Development Kits (SDKs) für Verschlüsselung integrieren und nutzt die robuste Sicherheit von AWS. Dank der engen Integration mit AWS-Services und Verschlüsselungs-SDKs eignet er sich hervorragend für AWS-basierte Anwendungen. 

Der überzeugendste Grund für den Einsatz von KMS zur symmetrischen Verschlüsselung ist die Verwaltung gemeinsam genutzter geheimer Schlüssel. Der sichere Umgang mit diesen Schlüsseln ist oft die größte Herausforderung bei der Verschlüsselung. Amazon KMS umgeht diese Schwierigkeiten elegant durch das Envelope-Encryption-Verfahren. Dabei werden die Schlüssel zusammen mit den Daten verschlüsselt. Sie verlassen sich dadurch in erster Linie auf einen Master-Schlüssel in einem Hardware-Sicherheitsmodul, auf den Unbefugte keinen Zugriff haben. Dieser Key-Wrapping-Mechanismus vereinfacht die Verschlüsselung und umgeht effektiv die komplexen Herausforderungen der Schlüsselverwaltung, Schlüsselrotation und anderer damit verbundener Aufgaben.

Amazon KMS ist jedoch möglicherweise unnötig, wenn Sie nur eine einfache Lösung für einen kleinen Anwendungsbereich benötigen. Außerdem handelt es sich um einen kostenpflichtigen Dienst, dessen Kosten bei intensiver Nutzung stark steigen können.

Verwenden wir nun Amazon KMS, um eine Datei in einer Python-Anwendung zu verschlüsseln.

Benötigte Module importieren

Für die Interaktion mit Amazon KMS müssen wir zunächst aws-encryption-sdk installieren und importieren – das AWS Encryption SDK für Python, das Ver- und Entschlüsselung vereinfacht. 

Erstellen Sie eine Datei namens main.py und fügen Sie den folgenden Code ein:

import aws_encryption_sdk

# Configuration
KEY_ARNs = [
    'arn:aws:kms:<REGION>:xxx:key/<KMS-KEY-ID>'
]

client = aws_encryption_sdk.EncryptionSDKClient()
kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(
    key_ids=KEY_ARNs)

Hinweis: Sie können die KMS-Schlüssel-ARN im AWS-KMS-Dashboard kopieren.

Datei verschlüsseln

Für die Verschlüsselung verwenden wir das AWS Encryption SDK. Das SDK ist eng in AWS KMS integriert und ermöglicht eine nahtlose Verschlüsselung.

Fügen Sie den folgenden Code zu main.py hinzu:

def encrypt_file(file_path, encrypted_path):
    with open(file_path, 'rb') as pt_file, open(encrypted_path, 'wb') as ct_file:
        with client.stream(
            mode='e',
            source=pt_file,
            key_provider=kms_key_provider
        ) as encryptor:
            for chunk in encryptor:
                ct_file.write(chunk)

Datei entschlüsseln

Auch zum Entschlüsseln der Datei verwenden wir das AWS Encryption SDK. Der Entschlüsselungsvorgang liest die verschlüsselte Datei und entschlüsselt die Daten anschließend nahtlos mithilfe der KMS-Schlüssel.

Fügen Sie die folgenden Befehle zu main.py hinzu:

def decrypt_file(encrypted_path, decrypted_path):
    with open(encrypted_path, 'rb') as ct_file, open(decrypted_path, 'wb') as pt_file:
        with client.stream(
            mode='d',
            source=ct_file,
            key_provider=kms_key_provider
        ) as decryptor:
            for chunk in decryptor:
                pt_file.write(chunk)

Funktionen aufrufen

Wir haben die Funktionen erstellt. Jetzt müssen wir sie aufrufen und das Python-Programm ausführen. Erstellen Sie zunächst eine Datei namens myfile.txt und fügen Sie beliebigen Inhalt ein.

Rufen Sie anschließend in main.py die folgenden Funktionen auf:

encrypt_file('myfile.txt', 'encrypted_file.txt')
decrypt_file('encrypted_file.txt', 'decrypted_file.txt')

Wenn wir zum Ausführen des Skripts python main.py aufrufen, verschlüsseln und entschlüsseln wir myfile.txt, ohne den Inhalt zu verändern. 

Hinweis: Der Einfachheit halber haben wir die Schlüssel-ID (als Teil der Schlüssel-ARN) fest im Code hinterlegt. Verwenden Sie bitte die Datei .env, um vertrauliche Angaben zu speichern.

Symmetrische Verschlüsselung mit PyNaCl SecretBox

PyNaCl ist eine Python-Anbindung an die Netzwerk- und Kryptografiebibliothek libsodium. Sie enthält zahlreiche Kryptografiewerkzeuge, darunter SecretBox, das Funktionen zur symmetrischen Verschlüsselung bietet. SecretBox überzeugt durch seine Einfachheit: Zum Ver- und Entschlüsseln unserer Daten benötigen wir nur einen Schlüssel.

Sehen wir uns an, wie Sie mit SecretBox eine sensible Datei in einer Python-Anwendung verschlüsseln. 

Erstellen Sie zunächst eine Datei namens nacl.txt und fügen Sie einen Platzhaltertext ein. Importieren Sie dann die erforderlichen Module in eine neue Python-Programmdatei namens sym.py:

from nacl import utils
from nacl.secret import SecretBox
import os

Als Nächstes generieren und laden wir den geheimen Schlüssel. Die Funktion generate_key generiert einen zufälligen Schlüssel. Die Funktion load_key lädt den generierten Schlüssel aus dem Dateipfad und gibt ihn zurück:

def generate_key(secret_key_file):
    secret_key = utils.random(SecretBox.KEY_SIZE)
    with open(secret_key_file, 'wb') as f:
        f.write(secret_key)
    return secret_key

def load_key(secret_key_file):
    if not os.path.exists(secret_key_file):
        print(f"Key file {secret_key_file} not found.")
    with open(secret_key_file, 'rb') as f:
        key = f.read()
    if len(key) != SecretBox.KEY_SIZE:
        print("Incorrect key length.")
    return key

Nun verschlüsseln wir die Datei. Die Funktion encrypt_file benötigt den file_path und den Schlüssel, um die sensible Datei zu verschlüsseln. Sie findet die Datei anhand ihres file_path, liest und verschlüsselt dann den Inhalt mithilfe des geheimen Schlüssels und schreibt den verschlüsselten Text in eine neue Datei mit der Erweiterung .enc:

def encrypt_file(file_path, key):
    if not os.path.exists(file_path):
        print(f"Key file {secret_key_file} not found.")
    secret_box = SecretBox(key)
    with open(file_path, 'rb') as f:
        plaintext = f.read()
    ciphertext = secret_box.encrypt(plaintext)
    with open(file_path+'.enc', 'wb') as f:
        f.write(ciphertext)

Wie zum Verschlüsseln benötigen wir auch eine Funktion zum Entschlüsseln. Die Funktion decrypt_file verwendet den file_path und den key, um eine Datei zu entschlüsseln. Zunächst prüft sie, ob eine verschlüsselte .enc-Datei vorhanden ist (das ist der Fall – wir haben sie im letzten Schritt erstellt). Anschließend liest sie den Inhalt und entschlüsselt ihn mit demselben geheimen Schlüssel. Schließlich schreibt sie den entschlüsselten Inhalt in eine neue Datei mit der Erweiterung .dec:

def decrypt_file(file_path, key):
    if not os.path.exists(file_path+'.enc'):
        print(f"Key file {secret_key_file} not found.")
    secret_box = SecretBox(key)
    with open(file_path+'.enc', 'rb') as f:
        ciphertext = f.read()
    plaintext = secret_box.decrypt(ciphertext)
    with open(file_path+'.dec', 'wb') as f:
        f.write(plaintext)

Im letzten Schritt rufen wir die gerade erstellten Funktionen auf:

secret_key_file = 'secret.key'

# generate key for encryption
key = generate_key(secret_key_file)
encrypt_file('nacl.txt', key)

# load key for decryption
key = load_key(secret_key_file)
decrypt_file('nacl.txt', key)

Führen Sie das Python-Programm jetzt mit dem Befehl sym.py in Ihrem Terminal aus.

Hinweis: Dieser Code ist nicht für den Einsatz in einer realen Anwendung oder einer Produktionsumgebung geeignet. Der sichere Umgang mit Verschlüsselungsschlüsseln ist komplex und erfordert zusätzliche Maßnahmen, etwa eine regelmäßige Schlüsselrotation. Diese wichtigen Sicherheitsmaßnahmen fehlen im Code.

Asymmetrische Verschlüsselung in Python

Bei der symmetrischen Verschlüsselung wird ein Schlüssel verwendet, bei der asymmetrischen Verschlüsselung hingegen zwei: ein öffentlicher Schlüssel zum Verschlüsseln und ein privater Schlüssel zum Entschlüsseln. Das ist wie ein abschließbarer Briefkasten. Jeder kann einen Brief durch den Schlitz einwerfen (Verschlüsselung), aber nur jemand mit einem passenden Schlüssel kann den Briefkasten öffnen und den Brief lesen (Entschlüsselung).

Asymmetrische Verschlüsselung eignet sich besonders für sichere Kommunikation über das Internet. Wenn Sie einer Person eine geheime Nachricht senden möchten, können Sie sie mit deren öffentlichem Schlüssel verschlüsseln. Nur diese Person kann sie dann mit ihrem privaten Schlüssel entschlüsseln. Asymmetrische Verschlüsselung schützt digitale Signaturen und Zertifikate – die Grundlage für Authentifizierung in der digitalen Welt.

Asymmetrische Verschlüsselung mit der Public/Private Box von PyNaCl

Wie lässt sich also asymmetrische Verschlüsselung in Python umsetzen? Sehen wir uns ein weiteres Tool von PyNaCl an: die Public/Private Box. 

Die Public/Private Box von PyNaCl ähnelt einem persönlichen Briefkasten. Sie bietet eine Schnittstelle zum Ver- und Entschlüsseln von Nachrichten mit zwei Schlüsseln: einem öffentlichen und einem privaten. Den zum Verschlüsseln von Nachrichten verwendeten öffentlichen Schlüssel können Sie frei weitergeben. Den privaten Schlüssel, der zum Entschlüsseln dient, müssen Sie jedoch geheim halten.

Erstellen Sie zunächst die Datei asym_nacl.txt und fügen Sie einen beliebigen Beispieltext ein. Damit Verschlüsselungsschlüssel sicher gespeichert und abgerufen werden können, benötigen wir passende Funktionen. Die Funktion save_key schreibt den Schlüssel in den file_path, während load_key den Schlüssel aus dem file_path abruft und zurückgibt. 

Fügen Sie den folgenden Code in eine neue Datei namens asym.py ein:

from nacl.public import PrivateKey, Box
import pickle

def save_key(file_path, key):
    with open(file_path, 'wb') as f:
        pickle.dump(key, f)

def load_key(file_path):
    with open(file_path, 'rb') as f:
        key = pickle.load(f)
    return key

Nun müssen wir Funktionen implementieren, um unsere sensible Datei zu ver- und entschlüsseln. Die Funktion encrypt_file verschlüsselt die Datei mithilfe öffentlicher Schlüssel und speichert sie mit verschlüsseltem Text in einer .enc-Datei. Die Funktion decrypt_file verwendet private Schlüssel, um die Datei zu öffnen (zu entschlüsseln), und speichert sie in einer .dec-Datei. 

Fügen Sie die folgenden Funktionen zu asym.py hinzu:

def encrypt_file(file_path, public_key):
    private_key = PrivateKey.generate()
    box = Box(private_key, public_key)

    with open(file_path, 'rb') as f:
        plaintext = f.read()

    ciphertext = box.encrypt(plaintext)

    with open(file_path+'.enc', 'wb') as f:
        f.write(ciphertext)

    return private_key

def decrypt_file(file_path, private_key, public_key):
    box = Box(private_key, public_key)

    with open(file_path+'.enc', 'rb') as f:
        ciphertext = f.read()

    plaintext = box.decrypt(ciphertext)

    with open(file_path+'.dec', 'wb') as f:
        f.write(plaintext)

Zum Schluss sehen wir uns die Ergebnisse unserer Arbeit an. Wir generieren zwei Schlüssel: einen öffentlichen Schlüssel, mit dem wir unsere Datei verschließen, und einen privaten Schlüssel, den wir speichern. Wenn wir auf die Datei zugreifen möchten, laden wir den gespeicherten privaten Schlüssel zusammen mit dem zugehörigen öffentlichen Schlüssel und entschlüsseln die Datei. 

Fügen Sie die abschließenden Funktionsaufrufe in die Datei asym.py ein:

private_key = PrivateKey.generate()
public_key = private_key.public_key

encryption_private_key = encrypt_file('asym_nacl.txt', public_key)
save_key('private.key', encryption_private_key)

encryption_private_key = load_key('private.key')
decrypt_file('asym_nacl.txt', private_key, encryption_private_key.public_key)

Führen Sie das Programm mit python asym.py in Ihrem lokalen Terminal aus.

Hinweis: Der obige Code veranschaulicht, wie Ver- und Entschlüsselung funktionieren. Für den Einsatz in realen Anwendungen ist er jedoch nicht sicher. Die Schlüsseldatei ist nicht geschützt. Wenn jemand Zugriff darauf erhält, kann diese Person Ihre Dateien öffnen.

Vor- und Nachteile der Public/Private Box von PyNaCl

Die Public/Private Box von PyNaCl bietet starke Sicherheit. Sie ermöglicht außerdem sichere Kommunikation über unsichere Kanäle und eignet sich dadurch ideal für die Kommunikation über das Internet.

Andererseits kann die Schlüsselverwaltung bei der Public/Private Box anspruchsvoll sein. Wir müssen private Schlüssel sicher speichern und sicherstellen, dass beim Verschlüsseln die richtigen öffentlichen Schlüssel verwendet werden. Asymmetrische Verschlüsselung kann außerdem langsamer sein als symmetrische, da sie komplexere Vorgänge umfasst.

Fazit

In diesem Artikel haben wir einige leistungsstarke Python-Tools zur Implementierung von Verschlüsselungsverfahren vorgestellt. Amazon KMS und PyNaCl SecretBox eignen sich hervorragend für symmetrische Verschlüsselung, während die Public/Private Box von PyNaCl ihre Stärken bei der asymmetrischen Verschlüsselung ausspielt.

Diese Tools bieten zahlreiche Vorteile für den sicheren Umgang mit Daten. Amazon KMS ist äußerst skalierbar, PyNaCl SecretBox bietet hohe Leistung und breite Kompatibilität und die Public/Private Box von PyNaCl ermöglicht besonders sichere Kommunikation. Zusammen bilden diese Tools ein umfassendes Verschlüsselungs-Toolkit.

Bei der Wahl eines Verschlüsselungsverfahrens müssen wir berücksichtigen, wie sensibel unsere Daten sind, in welcher Umgebung wir sie übertragen und wie wir die Schlüssel verwalten. Das perfekte Verschlüsselungsverfahren gibt es nicht, aber wir finden leicht dasjenige, das unseren Anforderungen am besten entspricht.

Sichern Sie Ihre Python-Apps ab

Finden und beheben Sie Python-Schwachstellen – kostenlos mit Snyk.

Keine Kreditkarte erforderlich.

Oder registrieren Sie sich mit Azure AD Docker ID Bitbucket

Mit der Nutzung von Snyk erklären Sie sich mit unseren Richtlinien einverstanden, einschließlich unserer Nutzungsbedingungen und Datenschutzerklärung.

Weiterlesen

blog feature ai violet
Blog

VulnBump: Können KI-Agenten anfällige Abhängigkeiten beheben, ohne den Build zu beschädigen?

VulnBump testet KI-Agenten anhand von 307 realen Dependency-Upgrades. Eine Lösung zählt nur, wenn die Sicherheitslücke behoben ist und Build sowie Tests weiterhin erfolgreich sind.

blog feature snyk container custom base recommendations
Blog

Evo Agentic AppSec: Sicherheit, die mit der KI-Entwicklung Schritt hält

KI-gestützte Entwicklung überholt herkömmliche Security-Workflows. Snyk Agentic AppSec setzt Security-Agenten ein, die Schwachstellen kontinuierlich finden, beheben und überprüfen – während Menschen die Maßstäbe festlegen.

Blog

Frontier-Modelle fanden die Schwachstellen. Nur der Angreifer fand die Angriffsketten.

Die statische Analyse fand die Schwachstellen, doch erst Live-Angriffstests bewiesen, wie sie sich zu Angriffen verketten lassen. Ein Vergleich von Evo COS, Claude Security und Claude Code Security.