Python für alle: Gute Gründe für das Lernen der beliebten Programmiersprache

Seite 2: Asymmetrische Verschlüsselung RSA

Inhaltsverzeichnis

Wie kurz und effizient Python-Code ist, zeigt unser gar nicht triviales Beispiel unter der Überschrift Implementierung der asymmetrischen Verschlüsselung RSA. Nachdem Sie Python installiert haben, fehlt nur PyCrypto, das Sie mit pip install pycryptodome installieren. Danach können Sie die wenigen Zeilen unseres Beispiels abtippen oder hier herunterladen und ausführen. Empfehlenswerte Editoren und IDEs stellen wir in dem Artikel "Python-Entwicklungsumgebungen für Einsteiger und Profis" vor.

Implementierung der asymmetrischen Verschlüsselung RSA

from Crypto.Util.number import inverse

# Basiswerte
p = 13
q = 17
n = p * q
phi = (p - 1) * (q - 1)

# Schl�sselgenerierung
e = 11
d = inverse(e, phi)
print("�ffentlicher Schl�ssel: ({:d},{:d})".format(e, n))
print("Privater Schl�ssel: ({:d},{:d})".format(d, n))

# Nachricht
nachricht = int(input("Beliebige Zahl zwischen 0 und 221 eintippen: "))

# Verschl�sseln
cypher = pow(nachricht, e, n)

# Entschl�sseln
print(str(pow(cypher, d, n))) 

Der Code generiert zuerst ein Schlüsselpaar. Anschließend benutzt er die Werte aus dem öffentlichen Schlüssel, um eine Benutzereingabe zu verschlüsseln. Mit dem privaten Schlüssel lässt sich daraus wieder die ursprüngliche Eingabe berechnen.

RSA nutzt aus, dass eine Primfaktorzerlegung großer Zahlen schwierig ist, während sich Multiplikationen leicht berechnen lassen. Python macht die Rechnung besonders einfach, weil die Sprache automatisch mit beliebig langen Ganzzahlen rechnet. Eine Beschreibung der mathematischen Grundlagen des Verfahrens ist verfügbar.

In den ersten beiden Zeilen definiert der Code die beiden Variablen p und q. Die beiden Primzahlen dienen als Grundlage für den öffentlichen und privaten RSA-Schlüssel. In einer realen Anwendung wären beides sehr große Primzahlen, das Beispiel zeigt aber, dass RSA auch mit kleinen Zahlen funktioniert. Mit den Variablen kann Python danach rechnen, beispielsweise um eine weitere Variable mit dem Ergebnis zu belegen:

phi = (p - 1) * (q - 1)

Unter dem Kommentar in unserem Beispiel in Zeile 9 # Schlüsselgenerierung steht ein Aufruf der Funktion inverse(). Einer der Vorteile von Python sind mächtige Bibliotheken, die Sie mit import in Ihren Code laden. Die Funktion findet die modulare Inverse von e. Der erweiterte euklidische Algorithmus, der diese Zahl berechnet, ist nicht ganz trivial, glücklicherweise aber schon fertig im Python-Modul crypto.Util.number implementiert. Es folgen zwei Aufrufe der Funktion print(), die die generierten Schlüssel auf die Konsole schreiben. Die Funktion format() ersetzt die Platzhalter für Ganzzahlen {d} mit den Werten der Variablen, die format() als Parameter erhält.

Von der Konsole akzeptiert Python mit input() auch Eingaben. Das Beispiel erwartet hier, dass Benutzer eine Zahl eintippen, die dann verschlüsselt wird:

nachricht = int(input("Beliebige Zahl"
 + " zwischen 0 und 221 eintippen: "))

RSA verschlüsselt immer nur Zahlen und keine Texte. Die Python-Zeile gibt erst den String mit der Aufforderung aus, sammelt die eingetippten Zeichen bis zum Enter ein und konvertiert sie mit der Funktion int() in eine Ganzzahl. Tippt ein Benutzer etwas anderes als Ziffern, schlägt die Konvertierung fehl und Python wirft eine Exception, also eine Fehlermeldung, die auf der Konsole landet. Wenn die Konvertierung klappt, steht die Zahl in der Variablen nachricht zur Verfügung.

Beliebig große Potenzen berechnet pow(). Mit einem dritten Parameter rechnet die Funktion das Ergebnis modulo der dritten Variable. pow(a, b) ergibt also ab, während pow(a, b, c) in einem Schritt ab % c rechnet. Das Verschlüsseln und Entschlüsseln mit RSA erledigt Python also jeweils in einem einzigen Funktionsaufruf:

# Verschl�sseln
cypher = pow(nachricht, e, n)
# Entschl�sseln
print(str(pow(cypher, d, n)))

Bei der Entschlüsselung pow(cypher, d, n) kommt wieder eine Zahl heraus. Die print()-Funktion erwartet aber eine Zeichenkette als Parameter. Die Konvertierung übernimmt die Funktion str(), die in Python jeden Datentypen in einen String verwandeln kann. Wenn alles geklappt hat, steht am Ende die Zahl auf dem Bildschirm, die Sie vorher eingetippt haben.

Probieren Sie unser RSA-Beispiel unbedingt mal aus! Verschlüsseln Sie dafür nicht nur verschiedene Zahlen, sondern machen Sie auch mal falsche Eingaben und bauen Sie auch Fehler in den Code ein. Dabei merken Sie, wie Python die Fehler meldet und versucht, Sie beim Debugging zur richtigen Zeile zu schicken. Sie dürfen das Beispiel auch gern erweitern, um beispielsweise Fehleingaben zu erkennen. Nur für ernsthafte Verschlüsselung sollten Sie unsere Python-Fingerübung nicht verwenden. Dafür gibt es gut getestete Implementierungen in Bibliotheken.

Im Folgenden geben wir einen groben Überblick der Flexibilität, die Sie mit Python bekommen können: Sei es Server mit Python automatisieren, den Raspi aufpeppen, Daten in Jupyter Notebooks visualisieren oder mit Django Ihrem Webprojekt neues Leben einhauchen.