Skip to main content

Symmetrische vs. asymmetrische Verschlüsselung: praktische Python-Beispiele

Artikel von
Headshot of Josh Amata

Josh Amata

blog feature fuzzing tools

15. Mai 2024

0 Min. Lesezeit

Symmetrische und asymmetrische Verschlüsselung sind die beiden gängigsten Methoden, um sensible Daten kryptografisch zu schützen. Bei diesen Verfahren werden Schlüssel verwendet, um eine unverschlüsselte Nachricht in eine verschlüsselte Nachricht (einen Chiffretext) umzuwandeln, die sich ohne die richtigen Schlüssel nur äußerst schwer entschlüsseln lässt. Bei der symmetrischen Verschlüsselung wird derselbe Schlüssel zum Ver- und Entschlüsseln von Daten verwendet. Die asymmetrische Verschlüsselung hingegen nutzt ein Schlüsselpaar aus öffentlichem und privatem Schlüssel, um sensible Daten zu ver- und entschlüsseln.

Systeme zur sicheren Datenübertragung und -speicherung, bei denen die Geheimhaltung von Daten im Vordergrund steht, verwenden diese Verschlüsselungsverfahren häufig. Beispielsweise verschlüsseln Ende-zu-Ende-Messaging-Anwendungen Nachrichten, bevor sie versendet werden. So wird verhindert, dass Angreifer Nachrichten im Klartext über einen Man-in-the-Middle-Angriff abfangen und lesen. Der Inhalt einer verschlüsselten Nachricht ist für Angreifer unlesbar.

Symmetrische und asymmetrische Verschlüsselung sind auch in anderen Anwendungsfällen hilfreich, etwa bei der Speicherung sensibler Informationen wie Passwörtern und Gesundheitsdaten. Systeme verschlüsseln solche Informationen üblicherweise, bevor sie auf Servern gespeichert oder zwischen Computern ausgetauscht werden.

Auch Anwendungen wie TLS/SSL verwenden diese Verfahren. Während des Handshakes sendet der Server seinen öffentlichen Schlüssel an den Client. Dieser erzeugt ein zufälliges Pre-Master-Secret und verschlüsselt es mit dem öffentlichen Schlüssel des Servers. Anschließend entschlüsselt der Server das Pre-Master-Secret mit seinem privaten Schlüssel. Danach erzeugen Server und Client unabhängig voneinander aus dem Pre-Master-Secret und weiteren Handshake-Parametern das Master-Secret.

Da beide dieselben Parameter verwenden, erzeugen Client und Server dasselbe Master-Secret, aus dem die Anwendung die Sitzungsschlüssel ableitet. Diese symmetrischen Schlüssel dienen dazu, Daten während der Sitzung zu ver- und entschlüsseln und so eine sichere Kommunikation zwischen Server und Client zu gewährleisten. Bei diesem Verfahren kommt asymmetrische Verschlüsselung zum sicheren und vertrauensfreien Austausch von Schlüsseln zum Einsatz. Der sichere Austausch symmetrischer Schlüssel ermöglicht eine schnelle und zuverlässige Datenübertragung.

Beide Verfahren tragen dazu bei, Sicherheitsrisiken zu mindern, die Daten gefährden können, etwa unbefugten Zugriff, Abfangen und Manipulation, Diebstahl sowie Verletzungen der Privatsphäre. In diesem Leitfaden befassen wir uns mit symmetrischer und asymmetrischer Verschlüsselung, setzen beide in Python um und erläutern Best Practices.

Voraussetzungen

Für dieses Tutorial benötigen Sie:

  • Grundkenntnisse in Python

  • Eine installierte Python-Toolchain (Version 3.7 oder höher) einschließlich pip

  • Ein Amazon Web Services (AWS)-Konto. Die Kontoerstellung und die Nutzung ausgewählter Dienste sind kostenlos.

Symmetrische Verschlüsselung verstehen

Bei der symmetrischen Verschlüsselung wird derselbe Schlüssel zum Ver- und Entschlüsseln verwendet. Dadurch ist sie schneller und effizienter als die asymmetrische Verschlüsselung. Der Ablauf sieht üblicherweise so aus:

  1. Schlüsselerzeugung: Der Absender oder ein vertrauenswürdiger Dritter erzeugt einen geheimen Schlüssel und teilt ihn anschließend sicher mit dem vorgesehenen Empfänger.

  2. Verschlüsselung: Der Absender wendet einen symmetrischen Verschlüsselungsalgorithmus an, beispielsweise Data Encryption Standard (DES), Triple DES (3DES) oder Advanced Encryption Standard (AES), und verschlüsselt damit die Klartextnachricht unter Verwendung des gemeinsamen geheimen Schlüssels. So wird aus dem Klartext ein Chiffretext.

  3. Datenübertragung: Der Absender überträgt den Chiffretext über einen unsicheren Kanal, etwa das Internet, an den Empfänger.

  4. Entschlüsselung: Der Empfänger wendet denselben symmetrischen Verschlüsselungsalgorithmus in umgekehrter Richtung an und verwendet dabei den gemeinsamen Schlüssel. So wird der Chiffretext entschlüsselt und die ursprüngliche Klartextnachricht wiederhergestellt.

Symmetrische Verschlüsselung ist effizienter und schneller und eignet sich daher besser als asymmetrische Verschlüsselung für aufwendige Aufgaben wie die Verschlüsselung von Dateien, Datenbanken oder sogar ganzen Festplattenpartitionen. So bleiben ruhende Daten auch dann unlesbar und verschlüsselt, wenn sie kompromittiert werden – solange der richtige Schlüssel fehlt.

Symmetrische Verschlüsselungsalgorithmen

Sehen wir uns DES, 3DES und AES genauer an und besprechen wir, wie Envelope Encryption die Schlüsselverwaltung erleichtert.

Data Encryption Standard (DES)

DES ist seit den 1970er-Jahren ein beliebter symmetrischer Verschlüsselungsalgorithmus. Er verwendet einen 56-Bit-Schlüssel, wodurch es 256 mögliche Schlüssel gibt (2 hoch 56). Etwa zwei Jahrzehnte lang galt DES als relativ sicher. Mit der heutigen Rechenleistung lässt er sich jedoch durch Brute-Force-Angriffe leicht knacken.

Triple Data Encryption Standard (3DES)

3DES ist eine verbesserte Version von DES, bei der drei DES-Schlüssel zum Einsatz kommen. Das Verfahren bietet ein höheres Sicherheitsniveau von 112 Bit. Es ist jedoch nach wie vor ineffizient, da der Schlüssel 168 Bit lang sein muss, um 112 Bit Sicherheit zu gewährleisten.

Advanced Encryption Standard (AES)

AES stammt aus den 1990er-Jahren und ist heute der Standard für symmetrische Verschlüsselung. Die Schlüssel bieten Sicherheitsstufen von 128, 196 oder 256 Bit. Die meisten Anwendungen verwenden 128-Bit-Schlüssel, da der Sicherheitsunterschied zwischen 128 und 256 Bit vernachlässigbar ist. AES ist schneller und sicherer als 3DES.

Envelope Encryption

Eine wesentliche Herausforderung bei der symmetrischen Verschlüsselung ist die Schlüsselverwaltung. Geht ein Schlüssel verloren, sind die Folgen gravierend, da Ver- und Entschlüsselung denselben Schlüssel verwenden. Envelope Encryption löst dieses Problem. Dabei kommen ein Data Encryption Key (DEK) und ein Key Encryption Key (KEK) zum Einsatz. Der DEK ist der primäre Schlüssel, mit dem die Anwendung Daten verschlüsselt; der KEK verschlüsselt den DEK.

Diese Verschlüsselung mit zwei Ebenen bietet zusätzliche Sicherheit, da ein erfolgreicher Angriff beide Schlüssel erfordern würde. Cloud-Computing-Umgebungen verwenden Envelope Encryption häufig, da sie mehr Sicherheit, Flexibilität und Skalierbarkeit bietet. Wie Sie weiter unten erfahren, stellen Cloud-Anbieter oft praktische Schnittstellen bereit, um Envelope Encryption zu nutzen und den Hauptschlüssel (KEK) vor Einsichtnahme zu schützen.

Symmetrische Verschlüsselung in Python implementieren

Erstellen wir eine Python-Anwendung, die Daten mithilfe symmetrischer Envelope Encryption ver- und entschlüsselt. Der AWS Key Management Service (KMS) bietet Envelope Encryption für die Schlüsselverwaltung sowie das AWS Encryption SDK für die Kommunikation mit dem Dienst.

Erste Schritte

Erstellen Sie zunächst ein Verzeichnis für Ihr Projekt:

$ mkdir encryption-demo && cd encryption-demo

Befolgen Sie anschließend diese Schritte, um im AWS-Dashboard einen symmetrischen KMS-Schlüssel zu erstellen. Dieser KMS-Schlüssel ist Ihr Customer Master Key (CMK).

Konfigurieren Sie die Zugriffsberechtigungen für Ihren Schlüssel und kopieren Sie anschließend den Amazon Resource Name (ARN) aus dem Bereich General configuration im Dashboard Ihres Schlüssels.

AWS Key Management Service-Konsole mit dem rot eingekreisten ARN eines kundenseitig verwalteten Schlüssels unter „Allgemeine Konfiguration“

Der ARN dient als CMK-Kennung für die Interaktion mit dem AWS Encryption SDK. Dabei handelt es sich um den KEK, der den generierten DEK verschlüsselt.

Installieren Sie anschließend die AWS CLI und konfigurieren Sie sie mit folgendem Befehl:

$ aws configure

Achten Sie bei der Konfiguration der AWS CLI darauf, dass das Profil über die erforderlichen CMK-Berechtigungen verfügt. So kann die Anwendung mithilfe der gespeicherten Anmeldedaten korrekt mit AWS KMS kommunizieren.

Den Rest der Anwendung erstellen

Für den Rest unserer Anwendung verwenden wir die Pakete aws-encryption-sdk und argparse. Das Paket aws-encryption-sdk implementiert das AWS Encryption SDK für Python. Installieren Sie diese Pakete mit folgendem pip-Befehl:

$ pip install aws-encryption-sdk argparse

Erstellen Sie nun eine Datei namens sym_encryptor.py und fügen Sie diesen Code hinzu, um die erforderlichen Module zu importieren:

import aws_encryption_sdk
from aws_encryption_sdk.exceptions import GenerateKeyError
import argparse

Fügen Sie anschließend den folgenden Code hinzu, um die Client- und Key-Provider-Klassen zu erstellen:

client = aws_encryption_sdk.EncryptionSDKClient()

kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[
    "<your-kms-ARN>"
])

Die Klasse EncryptionSDKClient stellt übergeordnete Client-Methoden wie encrypt, decrypt und stream für die Datenverschlüsselung bereit. Der Code konfiguriert die Klasse StrictAwsKmsMasterKeyProvider mit einer Liste von AWS-KMS-Masterschlüsseln für die Ver- und Entschlüsselung.

Übergeben Sie die ARN-Kennung des zuvor erstellten CMK. Durch die Übergabe des CMK-ARN kann der Code aus dem CMK einen Schlüssel ableiten, mit dem der Klartext verschlüsselt wird.

aws-encryption-sdk erzeugt, verschlüsselt und entschlüsselt den Datenschlüssel automatisch anhand des CMK. So wird die Schlüsselverwaltung vereinfacht.

Die Verschlüsselungsfunktion erstellen

Fügen Sie Ihrem Skript die folgende Funktion hinzu, um die Verschlüsselungsfunktion zu erstellen:

def encrypt(message):
    """
    Encrypts the passed message using the provided key.
    Returns the ciphertext of the message.
    """
    try:
        ciphertext, encryptor_header = client.encrypt(
            source=message,
            key_provider=kms_key_provider,
            encryption_context={
                'this is': 'not a secret',
                'but adds': 'some authentication'
            }
        )

        with open("encrypted.bin", "wb") as f:
            f.write(ciphertext)
        print("encryption complete")
    except GenerateKeyError:
        print("Error: data key generation from CMK failed, check ARN")

Diese Funktion übernimmt die Nachricht als Binärdaten und verschlüsselt sie mithilfe der Client-Methode encrypt(). Die Methode encrypt akzeptiert die zu verschlüsselnden Daten, die Key-Provider-Klasse und den Verschlüsselungskontext.

Wenn Sie die zuvor erstellte Key-Provider-Klasse übergeben, generiert der Client anhand des CMK einen Data Encryption Key und verschlüsselt die Daten. Der Client gibt den Chiffretext und einen Encryptor-Header zurück, der Informationen zur Überprüfung der Authentizität enthält. Der Verschlüsselungskontext ist ein Wörterbuch mit Informationen aus dem Encryptor-Header, den der Client zurückgibt.

Die Entschlüsselungsfunktion erstellen

Fügen Sie Ihrem Skript die folgenden Codezeilen hinzu, um die Entschlüsselungsfunktion zu erstellen:

def decrypt(ciphertext):
    """
    Decrypts the passed ciphertext using the provided key.
    Returns the original decrypted message.
    """   
    try:
        original_text, decryptor_header = client.decrypt(
            source=ciphertext,
            key_provider=kms_key_provider,
        )

        with open("decrypted.bin", "wb") as f:
            f.write(original_text)
        print("decryption complete")
    except GenerateKeyError:
        print("Error: data key generation from CMK failed, check ARN")

Diese Funktion übernimmt den Chiffretext und ruft die Methode decrypt() des Clients auf. Key-Provider und Chiffretext werden als Argumente übergeben. Die Methode decrypt funktioniert ähnlich wie die Methode encrypt. Sie leitet aus dem konfigurierten CMK einen Datenschlüssel ab und macht die Verschlüsselung rückgängig, indem sie denselben Schlüssel und Algorithmus auf die Daten anwendet. Die Methode gibt den entschlüsselten Text und einen Decryptor-Header zurück, der dem Encryptor-Header ähnelt. In realen Anwendungen helfen diese Header bei der Überprüfung der Daten, da sie dieselben Informationen enthalten, darunter Cipher Suite, ARN und Verschlüsselungskontext.

Eine Kommandozeilenanwendung erstellen

Damit sich die Anwendung leichter testen lässt, wandeln wir sie in eine Kommandozeilenanwendung um, die Befehlszeilenargumente verarbeitet. Fügen Sie den folgenden Code hinzu:

def parse_arguments():
    parser = argparse.ArgumentParser(description="Encrypt/Decrypt files")
    parser.add_argument("-i", metavar="[file]", type=str, required=False, help="file to encrypt/decrypt")

    group = parser.add_mutually_exclusive_group()
    group.add_argument("-e", "--encrypt", action="store_true", help="encrypt mode")
    group.add_argument("-d", "--decrypt", action="store_true", help="decrypt mode")

    args = parser.parse_args()
    return args

# Parse command-line arguments
args = parse_arguments()

file_name = args.i
if file_name:
    with open(file_name, "rb") as f:
        data = f.read()
    if args.encrypt:
        encrypt(data)
    elif args.decrypt:
        decrypt(data)
    else:
        print("must provide encryption/decryption mode: (-e/-d)")

Dieser Code verarbeitet die Befehlszeilenargumente. Er legt ein Schlüssel-Flag sowie Flags für die Auswahl des Ver- oder Entschlüsselungsmodus fest. Speichern Sie die Datei und führen Sie folgenden Befehl aus:

$ python sym_encryptor.py --help

Die Ausgabe sieht folgendermaßen aus:

usage: sym_encryptor.py [-h] [-i [file]] [-e | -d]

Encrypt/Decrypt files

options:
  -h, --help 	    show this help message and exit
  -i [file]  	    file to encrypt/decrypt
  -e, --encrypt  encrypt mode
  -d, --decrypt  decrypt mode

Die Anwendung testen

Erstellen Sie zum Testen der Anwendung zunächst eine beliebige Textdatei wie die folgende:

$ cat > test
Hello World!

Führen Sie die Datei durch die Anwendung und geben Sie den Dateinamen sowie das Flag -e für den Verschlüsselungsmodus an.

$ python sym_encryptor.py -e -i test

Dadurch wird eine neue Datei encrypted.bin erstellt.

$ cat encrypted.bin

Die Ausgabe sieht ungefähr so aus:

���/Oֶ7E.~RoZР�IT2ƺ�0r%...

Diese Datei enthält den Chiffretext, den unsere Anwendung erstellt hat. Sie können dem Empfänger diese verschlüsselte Datei senden. Der Empfänger oder andere Beteiligte benötigen die richtigen KMS-Zugriffsberechtigungen für den CMK.

Die Datei entschlüsseln

Um den Entschlüsselungsvorgang zu simulieren, führen Sie die verschlüsselte Datei durch die Anwendung:

$ python sym_encryptor.py -d -i encrypted.bin

Sie erhalten die Meldung „decryption complete“.

Der Code erstellt in Ihrem Verzeichnis eine neue Datei namens decrypted.file, wie hier gezeigt:

$ cat decrypted.bin
Output:
Hello World!

Wir haben den ursprünglichen Text nun erfolgreich wiederhergestellt, nachdem wir die Nachricht mithilfe symmetrischer Envelope Encryption mit AWS KMS ver- und entschlüsselt haben.

Asymmetrische Verschlüsselung verstehen

Bei der symmetrischen Verschlüsselung, die wir uns angesehen haben, wird derselbe Schlüssel zum Ver- und Entschlüsseln verwendet. Die asymmetrische Verschlüsselung nutzt dagegen ein Schlüsselpaar: einen öffentlichen Schlüssel, den der Benutzer öffentlich über das Internet oder andere Kanäle teilen kann, und einen privaten Schlüssel, den er geheim halten muss.

Sicherheit und Schlüsselverwaltung

Symmetrische Verschlüsselung ist zwar im Allgemeinen schneller und effizienter, doch die asymmetrische Verschlüsselung behebt die Sicherheitslücken, die beim sicheren Austausch eines Schlüssels zwischen Absender und Empfänger entstehen. Bei der asymmetrischen Verschlüsselung können Sie den öffentlichen Schlüssel frei mit allen teilen – sogar über unsichere Kanäle –, da sich die Dateien nur mit dem zugehörigen privaten Schlüssel entschlüsseln lassen. Der Empfänger hält diesen Schlüssel geheim.

Wenn Alice verschlüsselte Dateien sicher von Bob empfangen möchte, muss sie ein öffentliches und privates Schlüsselpaar erzeugen und Bob den öffentlichen Schlüssel senden. Sobald Bob den öffentlichen Schlüssel erhalten hat, kann er die Dateien verschlüsseln und über das Internet übertragen. Alice besitzt den privaten Schlüssel und ist daher die Einzige, die die Dateien entschlüsseln kann.

Möchte Alice anschließend eine verschlüsselte Datei an Bob senden, muss er sein eigenes öffentliches und privates Schlüsselpaar erstellen. Sobald er Alice den öffentlichen Schlüssel sendet, kann sie die Datei damit verschlüsseln und an Bob schicken. Bob entschlüsselt die Datei dann mit seinem privaten Schlüssel.

Für die asymmetrische Verschlüsselung benötigt jede Person ein eigenes, eindeutiges öffentliches und privates Schlüsselpaar.

Anwendungsfälle

Anwendungen nutzen asymmetrische Verschlüsselung vor allem für den sicheren Schlüsselaustausch in TLS/SSL-Protokollen, für sichere E-Mail-Kommunikation mit Pretty Good Privacy (PGP) und für digitale Zertifikate, die die Identität des Absenders oder Empfängers einer Nachricht bestätigen. Asymmetrische Verschlüsselung bietet ein hohes Maß an Sicherheit, ohne dass Schlüssel sicher ausgetauscht werden müssen.

Algorithmen für asymmetrische Verschlüsselung

Sehen wir uns einige beliebte Algorithmen für asymmetrische Verschlüsselung zur Generierung von Schlüsselpaaren an, darunter RSA, ElGamal und Curve25519.

Rivest-Shamir-Adleman (RSA)

RSA ist einer der ältesten und beliebtesten Algorithmen für asymmetrische Verschlüsselung. Er basiert auf der mathematischen Schwierigkeit, große zusammengesetzte Zahlen in ihre Primfaktoren zu zerlegen.

Bei der RSA-Schlüsselgenerierung werden zwei große Primzahlen ausgewählt, das Modulo und die Eulersche Phi-Funktion berechnet und daraus die Komponenten des privaten und öffentlichen Schlüssels abgeleitet. RSA ist nahezu überall zu finden. Bei ausreichend großen Schlüssellängen – mindestens 2048 Bit – ist der Algorithmus äußerst sicher, jedoch rechenintensiver als andere Algorithmen.

ElGamal

ElGamal basiert auf der Lösung des diskreten Logarithmusproblems. Dieser Algorithmus ist schneller als RSA, aber weniger sicher und erfordert für ein höheres Sicherheitsniveau größere Schlüssel. Bei der ElGamal-Schlüsselgenerierung werden eine zyklische Gruppe und ein Erzeuger ausgewählt. Anschließend werden die öffentlichen und privaten Schlüssel mithilfe modularer Exponentiation berechnet. Bei der Verschlüsselung wird der Klartext randomisiert und mit dem öffentlichen Schlüssel des Empfängers multipliziert.

Curve25519

Curve25519 zählt zu den schnellsten und sichersten Algorithmen der Elliptic Curve Cryptography (ECC). Der Algorithmus eignet sich für den Schlüsselaustausch und digitale Signaturen. ECC-Algorithmen bieten starke Sicherheit bei kürzeren Schlüsseln als RSA.

ECC nutzt die mathematischen Eigenschaften elliptischer Kurven über endlichen Körpern. Bei der Schlüsselgenerierung werden eine elliptische Kurve und ein Basispunkt ausgewählt. Anschließend werden die öffentlichen und privaten Schlüssel durch skalare Multiplikation auf der Kurve berechnet.

ECC wird vor allem in Umgebungen mit begrenzten Ressourcen und auf Geräten wie IoT- und Blockchain-Systemen eingesetzt. Die Berechnungen sind effizienter, während das Sicherheitsniveau ähnlich hoch bleibt wie bei RSA.

Asymmetrische Verschlüsselung in Python implementieren

Erstellen Sie zunächst mit dem folgenden Befehl eine neue Datei asym_encryptor.py in Ihrem Projektverzeichnis:

$ touch asym_encryptor.py

Importieren Sie die folgenden Bibliotheken:

from nacl.public import PrivateKey, PublicKey, SealedBox
from nacl.exceptions import TypeError, CryptoError
import argparse

Das Modul nacl.public enthält Klassen zum Generieren privater/öffentlicher Schlüsselpaare sowie zugehörige Methoden für die Verschlüsselung und Entschlüsselung. Die Klassen PrivateKey und PublicKey initialisieren die zugehörigen Schlüssel anhand einer Bytefolge. SealedBox verschlüsselt und entschlüsselt Nachrichten, die an ein bestimmtes Schlüsselpaar gerichtet sind. Der Befehl importiert außerdem die Ausnahmeklassen TypeError und CryptoError zur Fehlerbehandlung.

Eine Hilfsfunktion erstellen

Erstellen Sie als Nächstes eine Hilfsfunktion zum Generieren von Schlüsselpaaren:

def generate_keys():
    """
    Generates a new key pair
    """
    private_key = PrivateKey.generate()
    public_key = private_key.public_key
    with open("prv.key", "wb") as f:
        f.write(private_key.encode())
    with open("pub.key", "wb") as f:
        f.write(public_key.encode())
    print("generated private/public key pair")

Mithilfe des ECC-Algorithmus Curve25519 generiert diese Funktion über die Methode generate() ein zufälliges PrivateKey-Objekt sowie den zugehörigen öffentlichen Schlüssel. Anschließend schreibt sie die generierten Schlüssel in die entsprechenden Dateien.

Eine Funktion zum Verschlüsseln von Nachrichten erstellen

Fügen Sie nun die folgende Funktion hinzu, um Nachrichten mit dem öffentlichen Schlüssel zu verschlüsseln:

def encrypt(message, receiver_public_key):
    """
    Encrypts the given message with the public key.
    Returns the ciphertext of the message.
    """
    try:
        with open(receiver_public_key, "rb") as f:
            rpk = PublicKey(f.read())

        box = SealedBox(rpk)
        ciphertext = box.encrypt(message)

        with open("encrypted.bin", "wb") as f:
            f.write(ciphertext)
        print("public key encryption completed")
    except ValueError:
        print("Error: public key must be exactly 32 bytes long, check keys")

Diese Funktion akzeptiert eine binär codierte Nachricht im Klartext, die verschlüsselt werden soll, sowie eine Zeichenfolge mit dem Speicherort des öffentlichen Schlüssels. Anschließend lädt sie den öffentlichen Schlüssel und initialisiert ihn mit der Klasse PublicKey. Danach initialisiert sie eine SealedBox mit dem öffentlichen Schlüssel.

Die Entschlüsselungsfunktion erstellen

PyNaCl unterstützt asymmetrische Verschlüsselung mit zwei Klassen: Box und SealedBox. Box erstellt für die Verschlüsselung einen gemeinsamen Schlüssel aus dem privaten Schlüssel des Absenders und dem öffentlichen Schlüssel des Empfängers. Für die Entschlüsselung sind private und öffentliche Schlüssel erforderlich. So lässt sich kryptografisch nachweisen, wer die Nachricht verfasst hat.

Für die Entschlüsselungsfunktion verwenden wir die Klasse SealedBox. Damit ist die Ver- und Entschlüsselung mit einem Schlüsselpaar möglich, ohne einen kryptografischen Nachweis der Urheberschaft. Zur Verschlüsselung initialisieren wir SealedBox mit dem öffentlichen Schlüssel und rufen die Methode encrypt() mit der zu verschlüsselnden Nachricht auf. Anschließend schreiben wir den zugehörigen Geheimtext in eine Datei im Arbeitsverzeichnis.

Fügen Sie der Anwendung den folgenden Code hinzu:

def decrypt(ciphertext, receiver_private_key):
    """
    Decrypts the given message with the private key.
    Returns the original decrypted message.
    """
    with open(receiver_private_key, "rb") as f:
        secret_key = PrivateKey(f.read())

    try:
        box = SealedBox(secret_key)
        decrypted_text = box.decrypt(ciphertext)

        with open("decrypted.file", "wb") as f:
            f.write(decrypted_text)
        print("private key decryption completed")
    except TypeError:
        print("Error: invalid ciphertext")
    except CryptoError:
        print("Error: decryption failed, make sure keys are correct")

Diese Funktion akzeptiert den zu entschlüsselnden Geheimtext und den privaten Schlüssel. Sie lädt den privaten Schlüssel und initialisiert ihn mit der Klasse PrivateKey. Anschließend initialisiert sie eine SealedBox mit dem privaten Schlüssel zur Entschlüsselung. Die Funktion entschlüsselt die Nachricht mithilfe der Methode decrypt() und speichert den entschlüsselten Text in einer Datei im Arbeitsverzeichnis.

Kommandozeilenargumente verarbeiten

Fügen Sie mithilfe des folgenden Codes die Verarbeitung von Kommandozeilenargumenten hinzu, damit Sie Ihre Anwendung einfacher testen können:

def parse_arguments():
    parser = argparse.ArgumentParser(description="Encrypt/Decrypt messages with Asymmetric Encryption")
    parser.add_argument("-i", metavar="[file]", type=str, required=False, help="file to encrypt/decrypt")
    parser.add_argument("-g", "--generate", action="store_true", help="generate keys")
    parser.add_argument("-p", metavar="[key]", type=str, required=False, help="key file")

    group = parser.add_mutually_exclusive_group()
    group.add_argument("-e", "--encrypt", action="store_true", help="encrypt mode")
    group.add_argument("-d", "--decrypt", action="store_true", help="decrypt mode")

    args = parser.parse_args()
    return args

# Parse command-line arguments
args = parse_arguments()

if args.generate:
    generate_keys()
else:
    file_name = args.i
    if file_name:
        with open(file_name, "rb") as f:
            data = f.read()
        key = args.p
        if key:
            if args.encrypt:
                encrypt(data, key)
            elif args.decrypt:
                decrypt(data, key)
            else:
                print("must provide encryption/decryption mode: (-e/-d)")
        else:
            print("provide key for encryption/decryption with -p flag")

Dieser Code verarbeitet die Kommandozeilenargumente und setzt Flags, mit denen Sie zwischen Verschlüsselungs- und Entschlüsselungsmodus wählen, Schlüsselpaare generieren und Dateien übergeben können.

Speichern Sie die Datei und führen Sie den folgenden Befehl aus:

$ python asym_encryptor.py --help

Die Ausgabe sieht folgendermaßen aus:

usage: asym_encryptor.py [-h] [-i [file]] [-g] [-p [key]] [-e | -d]

Encrypt/Decrypt messages with Asymmetric Encryption

options:
  -h, --help  	show this help message and exit
  -i [file]   	file to encrypt/decrypt
  -g, --generate  generate keys
  -p [key]    	key file
  -e, --encrypt   encrypt mode
  -d, --decrypt   decrypt mode

Die Anwendung testen

Erstellen Sie zum Testen der Anwendung eine beliebige Textdatei, zum Beispiel die folgende:

$ cat > test
Hello World!!!

Generieren Sie mit dem folgenden Befehl Schlüsselpaare für den Test, bevor Sie die Datei verschlüsseln:

$ python asym_encryptor.py -g

Die Ausgabe sieht folgendermaßen aus:

generated private/public key pair

Mit diesem Befehl werden die privaten/öffentlichen Schlüsselpaare im Projektverzeichnis erstellt.

Führen Sie nun den folgenden Befehl aus, um die Textdatei mit dem generierten öffentlichen Schlüssel zu verschlüsseln:

$ python asym_encryptor.py -e -p pub.key -i test

Die Ausgabe lautet:

public key encryption completed

Die Anwendung erstellt den Geheimtext und speichert ihn im Projektverzeichnis als encrypted.bin. Diese verschlüsselte Datei ist vollständig unlesbar. Entschlüsseln lässt sie sich nur mit dem zum öffentlichen Schlüssel gehörenden privaten Schlüssel, wie im folgenden Beispiel:

$ python asym_encryptor.py -d -p prv.key -i encrypted.bin

Die Ausgabe sieht folgendermaßen aus: 

private key decryption completed

Die Anwendung hat die entschlüsselte Datei nun im Projektverzeichnis als decrypted.file gespeichert. Lesen Sie die entschlüsselte Datei mit dem folgenden Befehl:

$ cat decrypted.file

Nach Abschluss sehen Sie die Ausgabe “Hello World!!!”. 

Damit haben wir eine Klartextdatei erfolgreich asymmetrisch ver- und entschlüsselt.

Sicherheitsaspekte und Best Practices für symmetrische und asymmetrische Verschlüsselung

Ein wesentlicher Nachteil symmetrischer Verschlüsselung ist die Schwierigkeit, Schlüssel sicher auszutauschen. Je mehr Teilnehmer ein System hat, desto schwieriger wird die Schlüsselverteilung. Asymmetrische Verschlüsselung umgeht dieses Problem mit öffentlichen und privaten Schlüsselpaaren. Bei der symmetrischen Verschlüsselung lassen sich mithilfe von Methoden wie Envelope Encryption höhere Sicherheitsniveaus erreichen.

Beachten Sie bei symmetrischer und asymmetrischer Verschlüsselung die folgenden Empfehlungen:

  • Nutzen Sie für die Schlüsselverwaltung in Anwendungen mit symmetrischen Schlüsseln Tools von Anbietern wie Google Cloud Platform (GCP) oder AWS, zum Beispiel AWS KMS.

  • Vermeiden Sie nach Möglichkeit RSA-Verschlüsselung, um Ihre Anwendungen zukunftssicher zu machen. Zu den Sicherheitsrisiken zählen zu kurze Schlüssel (weniger als 2048 Bit), die Hacker knacken können, sowie ungeeignete Initialisierungsparameter. RSA korrekt zu implementieren, ist schwierig.

  • Wählen Sie für sehr große Dateien symmetrische Verschlüsselung. Sie ist leistungsfähiger als asymmetrische Lösungen.

  • Wählen Sie Schlüssel, deren Länge zum jeweiligen Verschlüsselungsalgorithmus passt. Zu kurze Schlüssel schaffen Sicherheitslücken. Verwenden Sie keine unsicheren Algorithmen wie DES.

  • Entwickeln Sie keine eigenen kryptografischen Lösungen, da dabei leicht Fehler passieren.

Nutzen Sie Tools wie Snyk, um Sicherheitsprobleme in Ihrem Code zu erkennen und Empfehlungen zu erhalten. Mit der Snyk-Plattform können Sie Sicherheitslücken in Ihrem Code, Open-Source-Abhängigkeiten, Container-Images und Infrastructure-as-Code-Konfigurationen (IaC) scannen, beheben und priorisieren.

Berücksichtigen Sie bei der Wahl des Verschlüsselungstyps diese Faktoren, denn jede Methode hat ihre Stärken und Schwächen. In der Praxis können Sie symmetrische und asymmetrische Verschlüsselung kombinieren, um Effizienz und Sicherheit in Einklang zu bringen.

Snyk verwenden

Um zu sehen, wie Snyk Sicherheitslücken während der Entwicklung erkennt, testen wir unseren Code damit.

Erstellen Sie zunächst ein Snyk-Konto. Der Einstieg ist kostenlos.

Hero-Bereich der Snyk-Website mit Fokus auf Entwicklersicherheit, einer Oberfläche für Schwachstellenscans und einer stilisierten Hundeillustration

Nach der Registrierung leitet Snyk Sie zur folgenden Seite weiter. Dort können Sie angeben, wo sich der zu scannende Code befindet: auf GitHub, in Bitbucket Cloud oder über eine CLI.

Snyk-Einrichtungsbildschirm mit Integrationsoptionen für GitHub, Bitbucket Cloud und CLI, wobei GitHub ausgewählt ist.

Wählen Sie CLI aus und klicken Sie auf Nächster Schritt.

Befolgen Sie auf dem nächsten Bildschirm einen der aufgeführten Schritte, um die Snyk CLI zu installieren, und klicken Sie dann auf Nächster Schritt:

Installationsansicht der Snyk CLI mit Download der ausführbaren Datei und Befehlszeilenanweisungen für macOS, Windows und Linux.

Führen Sie als Nächstes den folgenden Befehl aus, um Ihren Computer zu authentifizieren:

$ snyk auth

Mit diesem Befehl wird ein Browserfenster geöffnet, in dem Sie zur Anmeldung aufgefordert werden. Sobald Sie den Vorgang abgeschlossen haben, bestätigt die Snyk CLI mit einer Meldung, dass die Authentifizierung erfolgreich war.

Terminal mit abgeschlossener Snyk-Authentifizierung und einem unkenntlich gemachten Token in der Anmelde-URL.

Klicken Sie nun auf Nächster Schritt.

Snyk-Sicherheitsscan-Leitfaden mit Anweisungen zum Scannen von Quellcode und dem Befehl `snyk code test`.

Klicken Sie auf Quellcode und folgen Sie dem Link Einstellungen > Snyk Code zu Ihrem Dashboard. Aktivieren Sie dort die Option Snyk Code aktivieren, damit Sie die Snyk CLI für Ihren Code ausführen können. Klicken Sie anschließend auf Änderungen speichern.

Seite mit Organisationseinstellungen für Snyk Code. Die Funktion ist aktiviert und zeigt die Schritte zum Hinzufügen von Projekten, Analysieren von Code und Anzeigen der Ergebnisse.

Führen Sie zum Testen Ihres Codes im Projektverzeichnis den folgenden Befehl aus:

$ snyk code test

Mit diesem Befehl werden Ihre Codedateien automatisch hochgeladen und auf Sicherheitslücken gescannt:

Terminal mit Ergebnissen der statischen Codeanalyse: sechs Path-Traversal-Probleme mittlerer Schwere in Python-Verschlüsselungsdateien.

Der Screenshot oben zeigt, dass unsere Anwendung eine Path-Traversal-Sicherheitslücke aufweist, über die Angreifer beliebige Dateien lesen können. Für unsere Demonstrationsanwendung können wir diese Sicherheitslücke im Code belassen. In umfangreicheren Codebasen stellt sie jedoch einen Angriffsvektor dar.

Wir haben Snyk erfolgreich verwendet, um unser Projekt auf Sicherheitslücken zu scannen.

Zusammenfassung

Symmetrische und asymmetrische Verschlüsselung unterscheiden sich darin, wie sie Schlüssel zum Ver- und Entschlüsseln von Dateien verwenden. Bei der symmetrischen Verschlüsselung kommt ein gemeinsamer Schlüssel zum Einsatz, bei der asymmetrischen ein öffentliches/privates Schlüsselpaar.

Dank ihrer einfachen Implementierung und hohen Rechenleistung eignet sich symmetrische Verschlüsselung besser für die Verschlüsselung großer ruhender Datenmengen. Asymmetrische Verschlüsselung eignet sich für die Übertragung kleinerer Datenmengen, etwa bei TLS/SSL und digitalen Zertifikaten.

In dieser Anleitung haben wir Envelope Encryption (eine Kombination aus symmetrischer und asymmetrischer Verschlüsselung) mit dem AWS Encryption SDK implementiert. Außerdem haben wir mit der Python-Bibliothek pynacl asymmetrische Ver- und Entschlüsselung umgesetzt. Dabei haben wir die Stärken und Schwächen beider Verschlüsselungsarten bei kürzeren Schlüsseln untersucht. Außerdem haben wir gezeigt, wie sich Plattformen wie Snyk nutzen lassen, um Anwendungen auf Sicherheitslücken zu scannen.

Jetzt wissen Sie mehr über Verschlüsselung und können diese Methoden einsetzen, um Ihre Anwendungen für sich und Ihre Nutzer sicherer zu machen. Verwenden Sie anschließend Snyk, um sicherzustellen, dass Ihr Ansatz sicher ist.

Weiterlesen

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.

feature insights context
Blog

Autonome Angriffe sind bereits Realität. Die Verteidigung muss Schritt halten.

Autonome Angreifer verkürzen das Zeitfenster für die Verteidigung. Erfahren Sie, wie kontinuierliches Erkennen, Beheben, Validieren und Verhindern Sicherheitsteams helfen kann, Schritt zu halten.

Blog

Warum KI-Coding-Agenten immer wieder fehlerhafte Zugriffskontrollen schreiben

KI-Coding-Agenten können Autorisierungslogik erzeugen, die kompiliert und die Prüfung besteht, dabei aber die Daten eines Mandanten für einen anderen offenlegt. Erfahren Sie, warum fehlerhafte Zugriffskontrollen schwer zu erkennen sind und wie Sie sie verhindern.