Symmetrische Verschlüsselung
Lernziele:
Ich kann Texte nach folgenden Verfahren ver- und entschlüsseln: Caesar, Vigenère, XOR.
Ich kann Python-Codes für die Caesar- und für die Vigenère-Verschlüsselung analysieren, korrigieren und erweitern.
Ich kann monoalphabetische von polyalphabetischen Verschlüsselungsverfahren unterscheiden und die beiden Begriffe erklären.
Ich kann die Caesar-Verschlüsselung von der zufälligen monoalphabetischen Verschlüsselung unterscheiden.
Ich kann erklären, wo und wie die Häufigkeitsanalyse verwendet werden kann, um Geheimtexte zu knacken.
Ich kann erklären, weshalb die symmetrische Verschlüsselung so heisst und wie sie sich von der asymmetrischen Verschlüsselung unterscheidet.
Ich kann die
ASCII-Tabelle verwenden, um das einer Binärzahl entsprechende Zeichen zu finden – und umgekehrt.
Ich kann (noch immer) ohne Taschenrechner Binärzahlen in Dezimalzahlen umwandeln und umgekehrt.
Ich kann erklären, worin sich die OR-Verknüpfung von der XOR-Verknüpfung unterscheidet.
Ich kann erklären, weshalb sich die XOR-Verknüpfung für die symmetrische Verschlüsselung eignet.
Ich verstehe die Begriffe unten (siehe Begriffe).
Übersicht
Das Ver- und Entschlüsseln von Nachrichten wird schon seit der Antike betrieben.
Folgende Übersicht zeigt eine mögliche Einteilung der bestehenden Verschlüsselungs-Verfahren:
Auf dieser Seite betrachten wir ein kleine Auswahl von symmetrischen Verschlüsselungsverfahren:
Von den klassischen Substitutionsverfahren betrachten wir die Caesar-Verschlüsselung als Beispiel einer monoalphabetischen Substituion und
die Vigenère-Chiffre als Beispiel einer polyalphabetischen Substitution.
Ausserdem betrachten wir die XOR-Verschlüsselung als Beispiel einer modernen symmetrischen Verschlüsselung. Modern ist sie insofern, als sie mit Einsen und Nullen operiert und damit auf sämtliche Daten in digitaler Form anwendbar ist.
Symmetrische und Asymmetrische Verschlüsselung
Bei der symmetrischen Verschlüsselung können Daten mit demselben Schlüssel (z.B. eine Zahl, ein Wort etc.) verschlüsselt und später wieder entschlüsselt werden. Deshalb heisst sie „symmetrisch“: der Schlüssel funktioniert in beide Richtungen. Das ist gut, wenn es eine Möglichkeit gibt, den Schlüssel sicher auszutauschen.
Bei der Kommunikation im Internet ist das schwierig: Bevor ich eine sichere Verbindung zu einem Server aufbauen kann, müsste ich diesem Server meinen Schlüssel geben – aber eben auf einem sicheren Weg. Ich könnte ihn vielleicht per Post schicken – aber das ist natürlich nicht praktikabel. Deshalb wird hier die asymmetrische Verschlüsselung verwendet. Dabei wird für die Verschlüsselung ein anderer Schlüssel verwendet als für die Entschlüsselung: Angenommen, mein Schlüssel A verschlüsselt meine Daten aber nur Schlüssel B entschlüsselt sie. Dann könnte ich Schlüssel A vervielfachen und allen zur Verfügung stellen, die mir auf sicherem Weg eine Nachricht senden wollen. Sie können die Nachrichten mit A verschlüsseln – und nur ich kann die verschlüsselten Nachrichten entschlüsseln, denn nur ich habe Schlüssel B.
Begriffe
Folgende Begriffe solltest du kennen:
Kryptologie: Wissenschaft / Lehre der Ver- und Entschlüsselung (altgr. kryptós = verborgen).
Klartext – cleartext, plaintext
Chiffrat – Geheimtext, ciphertext, verschlüsselter Text
Schlüssel – key: Zum Beispiel ein Text oder ein Wert, mit dem der Klartext in das Chiffrat und das Chirffat wieder in den Klartext gewandelt werden kann. Der Schlüssel alleine reicht noch nicht aus, um einen verschlüsselten Text zu entschlüsseln: Es braucht auch das richtige Verfahren.
Verschlüsselungsverfahren, auch Chiffre: Wandelt den Klartext in das Chiffrat und umgekehrt.
Schlüsselraum: Anzahl möglicher Schlüssel bei einem Verschlüsselungsverfahren:
Angabe in Binärstellen: 4-Bit: 16 mögliche Schlüssel; 10 Bit: 1024 mögliche Schlüssel.
Der Schlüsselraum für die Caesar-Verschlüsselung ist 25, also knapp 5 Bit.
Geheimalphabet: Ordnet die Klartextbuchstaben den Geheimtextbuchstaben zu – gibt es so nur bei der monoalphabetischen Substitution.
Caesar-Verschlüsselung (monoalphabetische Substitution)
Die Caesar-Verschlüsselung ist eine sehr einfache Form der monoalphabetischen Substitution. Bei der Substitution werden Buchstaben durch andere Buchstaben ersetzt (lat. substituere = „ersetzen“). Monoalphabetisch ist sie deshalb, weil sie nur ein (mono) Geheim-Alphabet benutzt. Bei der Caesar-Verschlüsselung ergibt sich das Geheimalphabet durch Verschiebung. Ist der Schlüssel 3, so wird jeder Buschstabe um 3 Stellen verschoben: Was im Geheim-Alphabet ein D ist, ist im richtigen Alphabet ein A usw.:
Der Name der Caesar-Verschlüsselung geht auf den römischen Feldherrn Gaius Julius Caesar zurück, der diese Methode zur Verschlüsselung vertaulicher Botschaften benutzte. Sicher ist die Methode heute keineswegs: Am Geheimtext lässt sich anhand von Mustern leicht erkennen, dass es sich um ein Substitutions-Verfahren mit Verschiebung des Alphabets handelt. Und es sind nur 25 verschiedene Schlüssel (Verschiebewerte) möglich. So geht es sehr schnell, diese durchzuprobieren und auf den richtigen Schlüssel zu kommen.
Caesar-Verschlüsselung mit Python programmieren
Programmiere einen Verschlüsselsungs-Algorithmus mit python! Nutze einen der folgenden Editoren:
Wenn du keine Idee hast, wie das gehen könnte: Lies folgende Schritte genau durch und überlege für jede Code-Zeile, ob du sie verstehst.
Schritt 1 – Klasse String importieren
Wir importieren die Klasse string für Elemente und Funkionen zu Zeichenketten (Texten).
Die Klasse string enthält zum Beispiel die feste Zeichenkette ascii_uppercase:
import string
print(string.ascii_uppercase)
Schritt 2 – Position eines bestimmten Buchstabens finden
Die Funktion find() gibt den Index (= die Position) eines bestimmten Buchstabens innerhalb einer Zeichenkette zurück. Wenn sie den gesuchten Buchstaben nicht findet, gibt sie den Wert -1 zurück.
import string
print(string.ascii_uppercase)
print(string.ascii_uppercase.find('C'))
Schritt 3 – Einen einzelnen Buchstaben verschlüsseln
Einen einzelnen Buchstaben können wir nun wie folgt „verschlüsseln“, also um x Stellen im Alphabet verschieben:
Index herausfinden (Position dieses Buchstabens im Alphabet, von 0 bis 25).
Index um Verschiebungswert (Schlüssel) erhöhen.
Buchstaben ersetzen durch jenen unter neuem Index.
import string
key = 5 # Um so viel wird verschoben
letter = "A"
print(letter)
index = string.ascii_uppercase.find(letter) # 1.
index = index + key # 2.
letter = string.ascii_uppercase[index] # 3.
print(letter)
Schritt 4 – Eine Zeichenkette verschlüsseln
Um nun eine Zeichenkette (ein Wort oder einen Text) zu verschlüsseln, führen wir die Befehle aus Schritt 3 für jeden Buchstaben der Zeichenkette aus. Dazu verwenden wir eine for-Schleife:
import string
key = 5 # Um so viel wird verschoben
plainText = "Veni vidi vici"
cipherText = ""
for letter in plainText.upper(): # für jeden Buchstaben in plainText...
index = string.ascii_uppercase.find(letter)
index = (index + key) % 26
letter = string.ascii_uppercase[index]
cipherText = cipherText + letter
print(cipherText)
Beachte Folgendes:
Die Funktion upper() macht aus jedem Buchstaben in plainText einen Grossbuchstaben. Dadurch enthält die Variable letter immer einen Grossbuchstaben – egal, ob der Buchstabe in plainText gross oder klein war. Das ist wichtig, denn in der Zeichenkette ascii_uppercase befinden sich nur Grossbuchstaben und die Funktion find() würde darin nichts finden, wenn letter einen Kleinbuchstaben enthielte.
Damit index nicht grösser als 25 wird, wird die Addition index + key mit dem Modulo-Operator ergänzt: x modulo 26 (x % 26) gibt den Rest der Division x / 26 zurück: Für alle Werte grösser 26 gibt diese Operation also an, um wieviel grösser der Wert ist. Für index = 22 (Buchstabe 'W') und key = 5 ergäbe sich der Rest 1. Der neue Buchstabe wäre dann 'B' ('A' ist an Position 0).
In der letzten Zeile in der for-Schleife wird jeweils der neue Buchstabe zu der Zeichenkette cipherText hinzugefügt.
Aufgabe 1 – Verschlüsselungs-Algorithmus verbessern
Das Programm in Schritt 4 gibt ein Chiffrat ohne Leerschläge aus: Anstelle eines Leerschlags wird jeweils ein 'E' ausgegeben. Das macht Sinn: Wenn find() ein Zeichen nicht findet, gibt es den Wert -1 zurück. -1 + 5 (Verschiebungswert) ergibt 4 – das ist die Position des Buchstabens E.
Überlege, welches Chiffrat sich mit anderem Schlüssel (Verschiebungswert) ergäbe. Ändere den Schlüssel entsprechend und überprüfe deine Überlegung.
Verbessere das Programm so, dass Leerschläge nicht verschoben werden, sodass das Chiffrat an den gleichen Stellen Leerschläge enthält wie der Klartext. Dein Programm soll erst den Klartext, dann das Chiffrat ausgeben.
Lösung:
- caesar_01.py
import string
key = 5
clearText = "Veni vidi vici"
print(clearText)
alphabet = string.ascii_uppercase
ciphertext = ""
for letter in clearText.upper():
if letter in alphabet:
index = alphabet.find(letter)
cIndex = (index + key) % 26
letter = alphabet[cIndex]
ciphertext = ciphertext + letter
print(ciphertext)
Aufgabe 2 – Verschlüsselungs-Algorithmus als Funktion
Ergänze die Funktion caesar(plainText, key), sodass sie den verschlüsselten Text (Chiffrat) zurückgibt:
Nutze die Funktion caesar(), um das Chiffrat wieder zu etnschlüsseln…
import string
def caesar(clearText, key):
# deine Funktion
pass
klartext = "Veni vidi vici"
geheimtext = caesar(klartext, 7)
print(geheimtext)
Wenn alles funktioniert: Speichere deinen Code! (Link kopieren und ablegen.)
Lösung:
import string
def caesar(clearText, key):
alphabet = string.ascii_uppercase
ciphertext = ""
for letter in clearText.upper():
if letter in alphabet:
index = alphabet.find(letter)
index = (index + key) % 26
letter = alphabet[index]
ciphertext = ciphertext + letter
return ciphertext
klartext = "Veni vidi vici"
geheimtext = caesar(klartext, 7)
print(geheimtext)
print(caesar(geheimtext, -7))
Zusatzaufgaben (optional)
Nutze deine Funktion caesar für ein Programm, das alle möglichen Caesar-Schlüssel durchprobiert. Dein:e Nachbar:in gibt dir dann einen caesar-verschlüsselten Text ohne Angabe des Schlüssels und du musst den Klartext herausfinden.
Verbessere deine Funktion caesar, sodass sie Klein- und Grossbuchstaben unterscheidet: caesar(„Veni vidi vici“, 5) soll „ajsn Anin Anhn“ zurückgeben – und die Entschlüsselung mit -5 soll dann wieder „Veni vidi vici“ ergeben.
Zufällige monoalphabetische Substitution
Eine zufällige monoalphabetische Substitution ist weniger leicht zu knacken als beispielsweise eine Substituion gemäss der Caesar-Methode. Hier wird für jeden Buchstaben eine andere (wenn möglich zufällige) Verschiebung festgelegt. So wird jedem Buchstaben ein anderer zugewiesen. Etwa so:
Wieder entsteht zwar nur ein Geheimalphabet, dieses zu knacken ist aber schwieriger als bei der Caesar-Methode, denn hier gibt es weit mehr mögliche Kombinationen:
“Der erste Buchstabe „A“ kann an eine von 26 möglichen Alphabetpositionen platziert werden. Für den zweiten Buchstaben „B“ gibt es dann noch 25 mögliche Plätze zur Auswahl, für den dritten 24, und so weiter. Insgesamt berechnen sich so 26·25·24·23···4·3·2·1 […] Möglichkeiten zur Verwürfelung des Alphabets. Das sind ungefähr 4·1026 Fälle und entspricht etwa 88 bit.” (wikipedia.org/wiki/Monoalphabetische_Substitution)
Ist die zufällige monoalphabetische Substitution damit sicher? Nein, denn dank der Häufigkeitsanalyse ist auch ein Geheimtext, der nach dieser Methode verschlüsselt wurde, leicht zu knacken:
Häufigkeitsanalsye
Die Häufigkeitsanalsye macht sich zu nutzen, dass die Buchstaben in einer Sprache in einer bestimmten Häufigkeit vorkommen, für einen Text in deutscher Sprache ist die Häufigkeit der einzelnen Buchstaben wie folgt:
Um nun einen Geheimtext zu entschlüsseln, könntest du wie folgt vorgehen:
Du zählst, wie oft jeder Buchstabe im Geheimtext vorkommt und ordnest die Buchstaben des Geheimtexts nach Häufigkeit.
Vorausgesetzt du weisst, dass der Klartext in deutscher Sprache verfasst ist, kannst du nun annehmen, dass der häufgiste Buchstaben im Geheimtext wohl einem 'E' im Klartext entspricht, der zweithäufigste einem 'N' usw.
Die Häufigkeiten der Geheimtext-Buchstaben stimmt nicht immer überein mit der Standard-Häufigkeit des entsprechenden Klartext-Buchstabens. Je kürzer der Text, desto eher kann sie abweichen. Klar: Im Text „Anna“ zum Beispiel kommt das 'E' überhaupt nicht vor und hat damit die Häufigkeit 0.
Du kannst diese Entschlüsselungsmethode hier ausprobieren:
Vigenère-Verschlüsselung (polyalphabetische Substitution)
Die Vigenère-Chiffre funktioniert ähnlich wie die Caesar-Verschlüsselung; es wird aber nicht jeder Buchstabe um eine feste Anzahl Stellen verschoben. Der Verschiebungswert ändert sich fortlaufend, abhängig von einem Schlüsselwort. Anders als bei der monoalphabetischen Subsitution wird hier also nicht jedem Klartext-Buchstaben ein Geheimtext-Buchstabe zugeordnet. Stattdessen hängt der Geheimtext-Buchstabe von der Kombination aus Schlüsselwort- und Klartextbuchstabe ab. Dadurch entsteht nicht ein Geheimalphabet, sondern mehrere: Je nach Kombination, können für den Klartext-Buchstaben 'A' verschiedene Geheimtextbuchstaben entstehen.
Für den Text »Als Anna abends ass, ass Anna abends Ananas« mit dem Schlüsselwort FISCHERSFRITZ geht die Vigenère-Verschlüsselung wie folgt:
| Klartext | A | L | S | A | N | N | A | A | B | E | N | D | S | A | S | S |
| Position K | 0 | 11 | 18 | 0 | 13 | 13 | 0 | 0 | 1 | 4 | 13 | 3 | 18 | 0 | 18 | 18 |
| Schlüsselwort | F | I | S | C | H | E | R | S | F | R | I | T | Z | F | I | S |
| Position S | 5 | 8 | 18 | 2 | 7 | 4 | 17 | 18 | 5 | 17 | 8 | 19 | 25 | 5 | 8 | 18 |
| Geheimtext | F | T | K | C | U | R | R | S | G | V | V | W | R | F | A | K |
| Position G | 5 | 19 | 10 | 2 | 20 | 17 | 17 | 18 | 6 | 21 | 21 | 22 | 17 | 5 | 0 | 10 |
Beachte:
Das Schlüsselwort wird ständig wiederholt (sofern es, wie üblich, kürzer ist als der Klartext).
Unter jeder Textzeile ist die Position der jeweiligen Buchstaben im Alphabet angegeben:
Das Muster im Klartext ist, anders als bei der Caesar-Verschlüsselung, im Geheimtext nicht mehr erkennbar.
Aufgabe 3 – Vigenère von Hand auf Papier
Zwei 2er-Gruppen zusammen: Einigt euch auf ein einfaches Schlüsselwort (3 bis 6 Buchstaben).
Jede 2er-Gruppe für sich: Schreibt eine kurze Nachricht (2 bis 3 Wörter) auf ein Papier und verschlüsselt sie nach der Vigenère-Chiffre mit dem vereinbarten Schlüsselwort.
Schreibt M I T _ V I E L _ A B S T A N D und notiert zu jedem Buchstaben die Alphabet-Position.
Die Tabelle unten hilft dabei.
Teilt euch auf: A liest Buchstaben/Zahlen vor, B schaut in der Tabelle und antwortet mit entsprechenden Zahlen/Buchstaben.
Sendet die verschlüsselte Nachricht in elektronsischer Form der anderen Gruppe (z.B via Teams). Später können wir sie automatisch entschlüsseln.
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
One-Time-Pad (OTP)
Ist die Vigenère-Verschlüsselung sicher? Das hängt von der Länge und Zufälligkeit des Schlüsselwortes ab: kurze, einfach zu merkende Schlüsselwörter wie etwa “geheim” sind relativ unsicher; längere und zufälligere wie “wpfuVNaubLdshkYs” sind sicherer.
Als nicht-knackbar gilt das one-time-pad (OTP), eine Einmalverschlüsselung, bei der das Schlüsselwort mindestens so lange wie der Klartext selbst und die eben nur ein einziges mal verwendet wird.
Auch das Vigenère-Verfahren (mit wiederholt verwendeten Schlüsselwörtern) gilt angesichts heutiger Entschlüsselungsmethoden als unsicher.
Vigenère-Verschlüsselung in python programmieren
Aufgabe 4 – Konzept
Die Funktion vigenere(message, key_word) soll wie folgt funktionieren:
Der Funktion übergibt man die Nachricht (Klartext) und das Schlüsselwort.
Die Funktion gibt den verschlüsselten Text zurück.
Leerschläge sollen nicht verschlüsselt werden.
Folgend siehst du die Funktion caesar. Was musst du anpassen und ergänzen, damit sie zur Vigenère-Funktion wird und obige Anforderungen erfüllt? Notiere deine Änderungen als # Kommentare im Code. Vergleiche anschliessend mit der Lösung.
import string
def caesar(clearText, key):
alphabet = string.ascii_uppercase
ciphertext = ""
for letter in clearText.upper():
if letter in alphabet:
index = alphabet.find(letter)
index = (index + key) % 26
letter = alphabet[index]
ciphertext = ciphertext + letter
return ciphertext
Lösung:
import string
def caesar(clearText, key): # 1. Namen ändern, 2. key: Wort statt Zahl
alphabet = string.ascii_uppercase
ciphertext = ""
# Hier eine Variable (z.B. key_index) ergänzen (zählt durch Schlüsselwort).
for letter in clearText.upper():
if letter in alphabet:
index = alphabet.find(letter)
# Hier Verschiebewert (z.B. shift) aufgrund des aktuellen Schlüsselwort-Zeichens herausfinden, dann key_index erhöhen.
index = (index + key) % 26 # Anstelle von key muss der Verschiebewert stehen
letter = alphabet[index]
ciphertext = ciphertext + letter
return ciphertext
Aufgabe 5 – Vigenère-Funktion schreiben
Diese Aufgabe gibt es in drei Schwierigkeitsstufen:
1. Ohne Tipps
Schreibe die Funktion vigenere(message, key_word). Teste deine Funktion mit folgendem Code:
keyWord = "FischersFritz"
cipherText = vigenere("Als Anna abends ass, ass Anna abends Ananas", keyWord)
print(cipherText)
Prüfe, ob dein Programm Folgendes ausgibt. Falls nicht, musst du noch Änderungen vornehmen.
>>> FTK CURR SGVVWR FAK, CZW RFSR IUDSLK CUEESX
2. Mit Tipps
Lese die Tipps, falls du nicht weiterkommst.
Tipps:
Du benötigst zusätzliche Variablen (neben der Variable cyphertext, die du am Ende zurückgibst):
key_index zählt durch das Schlüsselwort. Wäre das Schlüsselwort „BOB“, so wäre key_index erst 0, dann 1, dann 2, dann wieder 0 etc. Du musst also schauen, dass key_index bei jedem Durchgang erhöht wird – aber nicht höher als die Länge des Schlüsselworts.
1)
shift_letter ist der aktuelle Buchstaben aus dem Schlüsselwort. Wäre das Schlüsselwort „BOB“, so wäre shift_letter erst 'B', dann 'O', dann 'B' etc. Verwende folgende Code-Zeile: shift_letter = key_word[key_index].upper(). Damit ist shift_letter immer ein Grossbuchstabe.
shift ist der aktuelle Verschiebewert. Wäre das Schlüsselwort „BOB“, so wäre
shift erst 1, dann 14, dann 1, dann wieder 1 etc.
2)
3. Mit fast fertigem Code
Ein Teil der Funktion steht schon.
Gehe den Code Zeile für Zeile durch. Wenn etwas unklar ist, fragst du die Lehrperson.
Ergänze den fehlenden Code. Beachte die Überlegungen aus Aufgabe 4. Lese die Tipps oben, falls du nicht weiterkommst.
import string
def vigenere(message, key_word):
alphabet = string.ascii_uppercase
ciphertext = ""
key_index = 0
for letter in message.upper():
if letter in alphabet:
index = alphabet.find(letter)
shift_letter = key_word[key_index].upper()
# dein Code...
# ...
# ...
ciphertext = ciphertext + letter
return ciphertext
keyWord = "FischersFritz"
cipherText = vigenere("Als Anna abends ass, ass Anna abends Ananas", keyWord)
print(cipherText)
Wenn alles funktioniert: Speichere deinen Code! (Link kopieren und ablegen.)
Lösung:
import string
def vigenere(message, key_word):
alphabet = string.ascii_uppercase
ciphertext = ""
key_index = 0
for letter in message.upper():
if letter in alphabet:
index = alphabet.find(letter)
shift_letter = key_word[key_index].upper()
key_index = (key_index + 1) % len(key_word)
shift = alphabet.find(shift_letter)
letter = alphabet[(index+shift)%26]
ciphertext = ciphertext + letter
return ciphertext
Aufgabe 6 – Vigenère-Funktion erweitern
Erweitere die Funktion um ein drittes Argument namens encrypt: vigenere(message, key_word, encrypt).
Wenn encrypt = 1 ist, soll die Funktion verschlüsseln, wenn encrypt = -1 ist, soll sie entschlüsseln.
Hierzu könnte encrypt einfach als Faktor verwendet werden, dann bräuchte es keine if-Abfrage.
Lösung:
import string
def vigenere(message, key_word, encrypt):
alphabet = string.ascii_uppercase
ciphertext = ""
key_index = 0
for letter in message.upper():
if letter in alphabet:
index = alphabet.find(letter)
shift_letter = key_word[key_index].upper()
key_index = (key_index + 1) % len(key_word)
shift = alphabet.find(shift_letter)
letter = alphabet[(index+shift*encrypt)%26]
ciphertext = ciphertext + letter
return ciphertext
Aufgabe 7 – Vigenère-Funktion testen
Teste deine (erweiterte) Vigenere-Funktion mit folgendem Code:
keyWord = "FischersFritz"
cipherText = vigenere("Als Anna abends ass, ass Anna abends Ananas", keyWord, 1)
print(cipherText)
print(vigenere(cipherText, keyWord, -1))
Prüfe, ob dein Programm Folgendes ausgibt. Falls nicht, musst du noch Änderungen vornehmen.
>>> FTK CURR SGVVWR FAK, CZW RFSR IUDSLK CUEESX
>>> ALS ANNA ABENDS ASS, ASS ANNA ABENDS ANANAS
Aufgabe 8 – Vigenère-Funktion anwenden (2er-Gruppen)
In Aufgabe 3 habt ihr Nachrichten von Hand verschlüsselt und euch gegenseitig gesendet. Entschlüsselt jetzt diese Nachricht mit euerer Vigenère-Funktion.
Mit dem vereinbarten Schlüsselwort könnt ihr nun beliebig Nachrichten austauschen, die niemand ohne Schlüsselwort lesen kann.
Moderne Verschlüsselung
Dieser Abschnitt behandelt hauptsächlich die XOR-Verschlüsselung. Sie ist eines der einfachsten Beispiele moderner symmetrischer Verschlüsselungs-Verfahren. Moderne Verfahren verschlüsseln nicht gedruckte oder handgeschriebene Texte, sondern digitale Daten (Texte, Bilder, Audio-Dateien, Videos, Code).
Eine Verschlüsselung über die Alphabet-Nummerierung macht wenig Sinn, denn:
Also kann die moderne Verschlüsselung bei den Einsen und Nullen ansetzen.
ASCII-Code
Der American Standard Code for Information Interchange wurde bereits 1963 veröffentlicht und dient, wie es der Name sagt, dem Austausch von Informationen. Die Idee ist klar: Wenn man schon in der Lage ist, Einsen und Nullen über Kupferleitungen hin- und her zu schicken, wäre es noch praktisch, auf diese Weise auch Information, also Text, auszutauschen. Dazu muss man sich einigen, welche Binährzahl welchem Text-Zeichen entspricht. Genau das macht der ASCII-Code:
In obenstehender Tabelle kann für jedes Zeichen die entsprechende Binärzahl (von links nach rechts) gelesen werden, indem man erst die Zahlenfolge der Spalte, dann jene der Zeile liest:
Der alte ASCII-Code weist nur 7 Bit auf, kann also maximal 128 Zeichen speichern. Er wurde mittlerweile vom UniCode-Standard abgelöst, damit auch Schriftzeichen anderer Sprachen Platz haben. Die Gross- und Kleinbuchstaben von A…Z haben auch im UniCode dieselben Nummern wie im ASCII-Code. So gesehen ist der ASCII-Code immer noch gültig.
Aufgabe 9 – ASCII-Binär-Dezimal
Verwende obige ASCII-Tabelle und dein Wissen zu Zahlensystemen (Umwandlungen binär-dezimal):
Welche Dezimalzahlen stehen für die Kleinbuchstaben b, g und q?
Welche Buchstaben entsprechen den Dezimalzahlen 70, 99 und 117?
Lösung:
b = 98 | g = 103 | q = 113
70 = F | 99 = c | 117 = u
XOR
XOR steht für Exclusive OR, also „Exklusives ODER“, und ist eine logische Verknüpfung. Logische Verknüpfungen finden wir auch in unserer Sprache:
Das ODER im Satz: „Ich ziehe eine Jacke an, wenn es windet oder wenn es regnet“ ist ein normales ODER. Das Resultat (Jacke an) ist wahr, wenn die erste Bedingung (es windet) wahr ist oder dann, wenn die zweite Bedingung wahr ist (es regnet) – aber auch dann, wenn beide Bedingungen wahr sind und es sowohl windet als auch regnet.
Das ODER im Satz:
„Willst du kurze oder lange Hosen anziehen?“ hingegen ist ein
exklusives3) ODER. Entweder kurze oder der lange Hosen – nicht beides.
Wenn wir 0 als falsch und 1 als wahr ansehen, ergeben sich für ODER und für XOR folgende Wahrheitstabellen:
Beachte für die XOR-Wahrheitstabelle:
Wenn A und B gleich sind, ist das Resultat 0, wenn sie verschieden sind, ist das Resultat 1
Die Operation funktioniert auch rückwärts: Resultat XOR B ergibt A!
Deshalb eignet sich die XOR-Operation für eine symmetrische Verschlüsselung!
Aufgabe 10 – Buchstaben ver-xor-en
Notiere anhand der
ASCII-Tabelle die Binärzahlen der Buchstaben
A und
t untereinander,
ermittle das Resultat ihrer XOR-Verknüpfung und
notiere das dem Resultat entsprechende
ASCII-Zeichen.
Lösung:
'A': 100'0001
't': 111'0100
--------------
res: 011'0101 = Zeichen '5'
ASCII-Codes mit XOR verschlüsseln
Mit XOR können wir Kombinationen von Nullen und Einsen verschlüsseln. Wir können sagen:
Geheimtext = Klartext XOR Schlüsselwort.
Folgend wird der erste Buchstabe des Klartexts mit dem ersten Buchstaben des Schlüsselworts „verxort“ (=mit dem XOR-Operator verrechnet):
Klartext: Aschenputtel, erster Buchstabe
A hat
ASCII-Code
100’0001 (= 65),
Schlüsselwort: Wolf, erster Buchstabe
W hat
ASCII-Code
101’0111 (= 87):
Die XOR-Operation ergibt 001’0110 (= 22). Dieser Zahl entspricht im ASCII-Code kein Buchstabe, sondern ein Steuerzeichen. Wenn es als Text angezeigt wird, sieht es vielleicht so aus: ‘<‘.
Die Verschlüsselung geht auch rückwärts: ‘<‘ XOR ‘W’ = ‘A’
Mit dieser Verschlüsselungsmethode können alle Binärzahlen und damit Daten in digitaler Form (Text, Videos, Fotos, etc.) verschlüsselt werden!
Aufgabe 11 – Geheimtext von Hand entschlüsseln
Gegeben ist folgender Geheimtext: 7 42 32 60. Die ASCII-Codes sind hier als Dezimalzahlen angegeben. Das Schlüsselwort heisst WOLF.
Schreibe die Dezimalzahlen als 7-stellige Binärzahlen nebeneinander auf ein Blatt Papier. Wenn möglich ohne Taschenrechner.
Schreibe unter die vier Binärzahlen die
ASCII-Codes für die vier Buchstaben des Schlüsselworts. Dazu benutzt du die
ASCII-Tabelle.
Führe die XOR-Operation Bit-für-Bit für jedes Binärzahl-Paar durch. So erhältst du die Binärzahlen des Klartexts.
Mit der
ASCII-Tabelle kannst du nun die Binärzahlen in Buchstaben wandeln und erhälst den Klartext.
Lösung:
Der Klartext Lautet: Pelz
Aufgabe 12 – XOR-Verschlüsselung in python programmieren (optional)
Schreibe eine Funktion crypt_xor(message_in, key_word):
Der Funktion übergibt man die Nachricht und das Schlüsselwort.
Die Funktion gibt den ver- bzw. entschlüsselten Text zurück.
Auch Satzzeichen und Leerschläge werden verschlüsselt.
Du kannst von der Vigenère-Funktion ausgehen, welche ebenfalls ein Schlüsselwort benutzt, das stets wiederholt wird. Überlege erst, welche Code-Zeilen du von der Vigenère-Funktion, die ja das Alphabet benutzt, nicht mehr brauchst. Beachte Folgendes:
Teste deine Funktion mit folgendem Code:
key = "WOLF"
cipher = crypt_xor("Nur ein garstiges Aschenputtel ist noch da. Das sitzt unten in der Asche, dem kann der Pantoffel nicht passen!", key)
print(cipher)
print(crypt_xor(cipher, key))
Prüfe, ob dein Programm funktioniert: Die erste Ausgabezeile kann von der untenstehenden abweichen, die zweite aber sollte den Klartext 1:1 wiedergeben.
>>>:>f2&"f0.>5#&+#$o
>>> 54')(':822#l/$;l(8,$f3.bf.?f$&8<#o9(#*"f>!l"2=l$,$#{o(#:o''9!l"2=l6!8)1))*w!%%?;l66<?#9n
>>> Nur ein garstiges Aschenputtel ist noch da. Das sitzt unten in der Asche, dem kann der Pantoffel nicht passen!
Lösung:
Ausführliche Version:
def crypt_xor(message_in, key_word):
message_out = ""
key_count = 0
for letter in message_in:
code_message_in = ord(letter)
code_key = ord(key_word[key_count])
code_message_out = code_message_in ^ code_key
letter = chr(code_message_out)
message_out = message_out + letter
key_count = (key_count + 1) % len(key_word)
return message_out
Kompakte Version:
def crypt_xor(message_in, key_word):
message_out = ""
key_count = 0
for letter in message_in:
letter = chr(ord(letter) ^ ord(key_word[key_count]))
message_out = message_out + letter
key_count = (key_count + 1) % len(key_word)
return message_out
Pixelbilder
Hier schauen wir uns ein einfaches Bild an, das bloss 64 Farbpunkte (Pixel) benötigt:
In einer Matrix von 8 Zeilen und 8 Spalten werden die Quadrate mit einer bestimmten Farbe gezeichnet.
Dieses Bild besteht aus 4 Farben. Die Farben sind als RGB-Hex-Werte angebegben:
0x2D1A2E = 2D rot, 1A grün und 2E blau
Aufgabe 13 – RGB-Hex-Werte binär und dezimal (optional)
Du erinnerst dich: Hexadezimalzahlen bestehen aus den Ziffern 0 bis 9 und zusätzlich aus den Buchstaben A bis F. Das heisst:
Mit einer Stelle können 16 Werte (0…F) dargestellt werden.
Im Binärsystem brauchst du für 16 Werte vier Bits.
Also reicht eine Hex-Stelle für vier Bits.
Also reichen zwei Hex-Stellen für 1 Byte (8 Bits)
Löse folgende Aufaben – wenn nötig mihilfe der Theorie zum Hexadezimalzahlen:
Wandle einen der Farbwerte aus obigem Bild in Binärwerte um. Du hast dann drei 8-Bit-Binärzahlen. Je einen für Rot, Blau und Grün.
Wandle die drei Binärzahlen in Dezimalzahlen um.
Stelle diese drei Dezimalzahlen im
RGB-Farbmixer ein und prüfe, ob die Farbe stimmt.
Lösung:
2D1A2E = 0010'1101 0001'1010 0010'1110 = 45 26 46
ADE3F9 = 1010'1101 1110'0011 1111'1001 = 173 227 249
6495ED = 0110'0100 1001'0101 1110'1101 = 100 149 237
3671F4 = 0011'0110 0111'0001 1111'0100 = 54 113 244
Bilder mit XOR verschlüsseln
Nachdem du obige Aufgabe gelöst hast, ist klar: Jedes Pixel des obigen Bildes besteht aus drei 8-Bit-Binärzahlen. Wenn wir diese Zahlen im Hexadezimalsystem notieren, sparen wir Platz: Statt 24 Stellen benötigen wir bloss 6 Stellen pro Pixel. Obiges Bild besteht aus folgenden RGB-Werten:
img_1 = [
['2D1A2E', '2D1A2E', '2D1A2E', 'ADE3F9', 'ADE3F9', '2D1A2E', '2D1A2E', '2D1A2E'],
['2D1A2E', '2D1A2E', 'ADE3F9', 'ADE3F9', 'ADE3F9', 'ADE3F9', '2D1A2E', '2D1A2E'],
['2D1A2E', 'ADE3F9', 'ADE3F9', 'ADE3F9', 'ADE3F9', 'ADE3F9', 'ADE3F9', '2D1A2E'],
['2D1A2E', 'ADE3F9', '2D1A2E', 'ADE3F9', 'ADE3F9', '2D1A2E', 'ADE3F9', '2D1A2E'],
['2D1A2E', '6495ED', '6495ED', '6495ED', '6495ED', '6495ED', '6495ED', '2D1A2E'],
['2D1A2E', '2D1A2E', '6495ED', '2D1A2E', '2D1A2E', '6495ED', '2D1A2E', '2D1A2E'],
['2D1A2E', '3671F4', '2D1A2E', '3671F4', '3671F4', '2D1A2E', '3671F4', '2D1A2E'],
['3671F4', '2D1A2E', '3671F4', '2D1A2E', '2D1A2E', '3671F4', '2D1A2E', '3671F4']
]
Jeder 6-stellige RGB-Hex-Wert seht für 24 Einsen oder Nullen. Wir können die XOR-Operation also auch bei Bildern vornehmen.
Aufgabe 14 – XOR mit kurzem Schlüssel
Nehmen wir einen einfachen Schlüssel, zum Beispiel:
Unser Schlüssel ist gleich lang wie der RGB-Wert eines einzelnen Pixels (3 Bytes oder 24 Bits). Wir wollen nun jedes Pixel des obigen Bildes mit dem Schlüssel xoren 4):
Berechne die resultierende Farbe für den ersten Pixel.
Wie sieht das verschlüsselte Bild wohl aus? Ist das Motiv (Tintenfisch) noch erkennbar? Überlege erst und vergleiche dann mit der Lösung.
Lösung Farbe erstes Pixel:
2D1A2E = 0010'1101 0001'1010 0010'1110
123456 = 0001'0010 0011'0100 0101'0110
RESULT = 0011'1111 0010'1110 0111'1000 = 0x3F2E78 = R63 G46 B120
Lösung verschlüsseltes Bild:
Aufgabe 15 – Überlegungen zur Schlüssellänge
Da siehst: Der einfache Schlüssel verändert das Bild. Aber es bleibt weiterhin erkennbar.
Warum ist das so? Überlege (oder diksutiert zu zweit) und vergleiche anschliessend mit der Lösung.
Vergleiche mit der Vigenère-Verschlüsselung: Wie sähe dort ein so einfacher Schlüssel aus?
Lösung:
Weil jedes Pixel mit dem gleichen Schlüssel xort wird, haben alle Pixel, die vorher die gleiche Farbe hatten, auch im verschlüsselten Bild die gleiche Farbe – einfach eine andere. Die Farben ändern sich zwar, aber das Muster bleibt gleich.
Vergleich mit Vigenère: Bei der Vigenère-Verschlüsselung verschlüsseln wir Buchstabe für Buchstabe – hier verschlüsseln wir Pixel für Pixel. Ein Schlüssel, der jedes Pixel gleich verschlüsselt, wäre bei Vigenère einfach ein einzelner Buchstabe – zum Beispiel 'D'. Die Buchstaben ändern sich zwar, aber das Muster bleibt gleich.
Aufgabe 16 – XOR mit langem Schlüssel
Nun verschlüsseln wir mit einem längeren Schlüssel. Wir nehmen nicht bloss einen sechsstelligen Hexwert, sondern fünf davon. Diese speichern wir in einer Liste:
key = [
0x123456,
0xABCDEF,
0x654321,
0xFEDCBA,
0x777777
]
Bei der Vigenère-Verschlüsselung wäre dies ein Wort aus fünf Buchstaben. Und wie bei Vigenère gehen wir auch hier gehen wir jedes Element des Schlüssels durch und beginnen dann wieder von vorne:
Pixel 1 wird mit Hexwert 1 verschlüsselt
Pixel 2 wird mit Hexwert 2 verschlüsselt
…
Pixel 6 wird mit Hexwert 1 verschlüsselt
…
Folgender Code zeichnet erst das originale Bild, wartet dann kurz, verschlüsselt das Bild mit obigem Schlüssel und zeichnet dann das verschlüsselte Bild:
Turtle_Bild_XOR
Versuche, den Code zu verstehen:
Einzeln: Verschaffe dir erste einen Überblick: Was hat es für Funktionen? Wo werden die Funktionen aufgerufen?
Einzeln: Gehe jede Funktion Zeile für Zeile durch. Wenn du unsicher bist, was eine bestimmte Zeile macht, notiere einen #Kommentar hinter die Zeile (z.B. #? – oder noch besser eine konkrete Frage).
Zu zweit: Tausch euch aus über euer Verständnis und eure Fragen. Wenn Fragen offen bleiben: Lehrperson fragen.
Ergänze den Code um weitere Zeilen, sodass er das verschlüsselte Bild 3 Sekunden lang anzeigt und es danach wieder entschlüsselt. Am Ende soll das entschlüsselte Bild angezeigt werden.
Zusatzaufgabe für Fortgeschrittene (optional)
Erstelle (mithilfe von AI) einen Code, der Bilder mit höherer Auflösung (z.B. im Format png) mit XOR ver- und entschlüsseln kann. Teste mit verschiedenen Bildern.
Zusätzliche Aufgaben zum Üben
Z1 – Caesar
Verschlüssle „XYLOPHON“ von Hand mit Caesar, in dem du um 7 Stellen nach hinten verschiebst.
Der Text „SOGAR SOLAR“ wurde mit Caesar -6 verschlüsselt:
Welcher positive Schlüsselwert führt zur gleichen Verschiebung wie -6?
Wie lautet der Originaltext?
Lösung:
EFSVWOVU
:
20
MIAUL MIFUL
Z2 – Zufällige monoalphabetische Substitution
Entschlüssle die Nachricht „OSMVAEJVPNRENJFYWNN“ von Hand. Sie wurde mit dem folgenden monoalphabetischen Verfahren verschlüsselt (Alphabet & Schlüssel):
ABCDEFGHIJKLMNOPQRSTUVWXYZ # Alphabet
SOGVNPKWEFLMUJDHZRAIYTBXCQ # Schlüssel
Tipp: Schreibe einen kurzen Code zum Entschlüsseln – das geht schneller und macht mehr Spass!
Lösung:
secret = "SOGVNPKWEFLMUJDHZRAIYTBXCQ"
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
message = "OSMVAEJVPNRENJFYWNN"
result = ""
for letter in message:
index = secret.find(letter)
result += alphabet[index]
print(result)
Z3 – Vigenère entschlüsseln
Entschlüssele folgenden nach Vigenère verschlüsselten Geheimtext mit dem Schlüsselwort TAUBE:
EIYCIK DYO WIANA MG DYS LTNX
Lösung:
LIEBER DEN SPATZ IN DER HAND
Z4 – Vigenère-Code erweitern
Verändere folgende Vigènere-Funktion so, dass auch Abstände verschlüsselt werden (und korrekt wieder entschlüsselt werden):
import string
def vigenere(message, key_word, crypt):
alphabet = string.ascii_uppercase
ciphertext = ""
key_index = 0
for letter in message.upper():
if letter in alphabet:
index = alphabet.find(letter)
shift_letter = key_word[key_index].upper()
key_index = (key_index + 1) % len(key_word)
shift = alphabet.find(shift_letter)
letter = alphabet[(index+shift*crypt)%26]
ciphertext = ciphertext + letter
return ciphertext
text = "Das Dschungelbuch"
key = "Balu"
cipher = (vigenere(text, key, 1))
print(cipher)
print(vigenere(cipher, key, -1))
Lösung:
In Zeile 4 das alphabet um ein Leerzeichen erängzen und
in Zeile 13 den Modulo-Operand der neuen Alphabet-Länge anpassen.
Z5 – Umwandlungen ASCII BIN DEC HEX
Wie lautet der Hexwert für das
ASCII-Zeichen G?
Wie lautet der Dezimalwert für das
ASCII-Zeichen f?
Welches Zeichen findet sich unter dem Hexwert 0x77?
Welches Zeichen findet sich unter dem Dezimalwert 61?
Lösung:
1. G: 100'0111 = 0x47
2. f: 110'0110 = 102
3. 0x77 = 111'0111 -> 'w'
4. 61 = 011'1101 --> '='
Z6 – XOR entschlüsseln
Entschlüssle den xor-verschlüsselten Text qxj mit dem Schlüssel !1+. Verwende die ASCII-Tabelle. Achte auf Gross-/Kleinschreibung.
Lösung: