Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
gf_informatik:verschluesselung:symmetrisch [2022-03-10 21:27] – hof | gf_informatik:verschluesselung:symmetrisch [2025-04-01 11:46] (aktuell) – [Vorgehen] hof | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
## Symmetrische Verschlüsselung | ## Symmetrische Verschlüsselung | ||
- | Wir können nun beliebige | + | Wir können nun beliebige |
{{ : | {{ : | ||
Zeile 27: | Zeile 27: | ||
* Statistische Methoden könnten die Entschlüsselung ermöglichen, | * Statistische Methoden könnten die Entschlüsselung ermöglichen, | ||
* Wiederkehrende Wörter, insbesondere am Anfang der Nachricht, fallen schnell auf. | * Wiederkehrende Wörter, insbesondere am Anfang der Nachricht, fallen schnell auf. | ||
- | * Die Enigma konnte im zweiten Weltkrieg auch deshalb geknackt werden, weil einige Wörter immer wieder auftauchten, | + | * Die [[wpde> |
* Ein Angreifer könnte einen verschlüsselten Block in eine Nachricht einfügen, ohne den genauen Klartext zu kennen. Damit könnte er die Nachricht verfälschen. | * Ein Angreifer könnte einen verschlüsselten Block in eine Nachricht einfügen, ohne den genauen Klartext zu kennen. Damit könnte er die Nachricht verfälschen. | ||
* Fällt dir ein Beispiel ein, wie dies ausgenützt werden könnte? | * Fällt dir ein Beispiel ein, wie dies ausgenützt werden könnte? | ||
Zeile 36: | Zeile 36: | ||
### Moderne Block-Ciphers | ### Moderne Block-Ciphers | ||
- | Moderne Kryptographie-Verfahren funktionieren ganz ähnlich, aber es gibt ein paar wesentliche Unterschiede: | + | Moderne Kryptographie-Verfahren funktionieren ganz ähnlich, aber es gibt ein zwei wesentliche Unterschiede: |
- | Statt einer simplen XOR Operation wird bei der Verschlüsselung jedes Blocks eine kompliziertere Funktion verwendet. Das Ziel dabei ist, dass jeweils nicht nur ein einzelnes Bit des Schlüssels und des Klartexts kombiniert werden, sondern dass möglichst alle Bits miteinander vermischt werden. | + | **1. Blockverschlüsselung**: |
Wir haben aber trotzdem noch ein Problem: komplett gleiche Blöcke werden weiterhin gleich verschlüsselt. Wiederholt sich eine Klartext-Sequenz exakt mit der Blockgrösse, | Wir haben aber trotzdem noch ein Problem: komplett gleiche Blöcke werden weiterhin gleich verschlüsselt. Wiederholt sich eine Klartext-Sequenz exakt mit der Blockgrösse, | ||
- | Aus diesem Grund werden die Blöcke nochmals miteinander **verkettet** (en. _chaining_): | + | **2. Verkettung**: |
+ | |||
+ | Der Ausdruck _Block Chain_ ist auch aus der Welt der Cryptowährungen bekannt, die auf dem exakt gleichen Prinzip aufbauen: Ein neuer Block in der Block Chain basiert auf allen vorhergehenden Transaktionen der Währung. | ||
{{ : | {{ : | ||
Zeile 49: | Zeile 51: | ||
{{ : | {{ : | ||
- | |||
### Herausforderung: | ### Herausforderung: | ||
Nimm den Full-Block-Coder aus der [[gf_informatik: | Nimm den Full-Block-Coder aus der [[gf_informatik: | ||
+ | |||
+ | **Achtung: | ||
+ | |||
+ | {{ : | ||
++++Lösung: | ++++Lösung: | ||
Zeile 151: | Zeile 156: | ||
</ | </ | ||
++++ | ++++ | ||
+ | ### Verkettung ausprobieren | ||
+ | |||
+ | Wende eine einfache Block-Verschlüsselung im ECB bzw. CBC-Modus an, und dokumentieren den Effekt in einem Dokument (OneNote, Word, Latex...). | ||
+ | * Wie sieht das verschlüsselte Bild aus? | ||
+ | * Was passiert mit anderen (längeren) Schlüsseln? | ||
+ | * Warum ist ein Schlüssel nur aus Grossbuchstaben ungünstig? | ||
+ | |||
+ | #### Vorgehen | ||
+ | |||
+ | Du benötigst ein Bild, z.B. {{: | ||
+ | |||
+ | Speichere den folgenden Code in VS Code. Der Code verwendet die OpenCV-Bibliothek zur Bildverarbeitung. Sie muss einmalig im Terminal mit `python -m pip install opencv-python` installiert werden. | ||
+ | |||
+ | * Führe den Code aus - was zeigt das Bild? | ||
+ | * Ändere den Code, um den Effekt von verschiedenen Schlüssellängen und von _Chaining_ auf das Chiffrat auszuprobieren! | ||
+ | * Dokumentiere die Resultate in OneNote / Word / Latex / Jupyter. | ||
+ | |||
+ | <code python block_coder.py> | ||
+ | import cv2 as cv | ||
+ | import numpy as np | ||
+ | import math | ||
+ | import random | ||
+ | |||
+ | def text_to_bytes(text): | ||
+ | """ | ||
+ | numbers = [] | ||
+ | for letter in text: | ||
+ | number = ord(letter) | ||
+ | numbers.append(number) | ||
+ | return numbers | ||
+ | |||
+ | def bytes_to_text(numbers): | ||
+ | """ | ||
+ | text = "" | ||
+ | for number in numbers: | ||
+ | letter = chr(number) | ||
+ | text += letter | ||
+ | return text | ||
+ | |||
+ | def binary_to_bytes(binstring): | ||
+ | binstring *= 8 # ensure we are byte-aligned | ||
+ | result = [] | ||
+ | for eight in range(0, len(binstring), | ||
+ | result.append(int(binstring[eight: | ||
+ | return result | ||
+ | |||
+ | def xor(one, two): | ||
+ | result = [] | ||
+ | for i in range(len(one)): | ||
+ | result.append(one[i] ^ two[i]) | ||
+ | return result | ||
+ | |||
+ | def block_encrypt(one, | ||
+ | # In reality, this would be a more complex operation, such as a sequence of | ||
+ | # [s-boxes](https:// | ||
+ | return xor(one, two) | ||
+ | |||
+ | def block_decrypt(one, | ||
+ | # In reality, this would be the inverse of block_encrypt. | ||
+ | return xor(two, one) | ||
+ | |||
+ | def encrypt(plain_bytes, | ||
+ | # random initialization vector | ||
+ | iv = random.randbytes(block_size) | ||
+ | |||
+ | # ensure our key material is divisible by block_size | ||
+ | key_bytes = key_bytes * block_size | ||
+ | |||
+ | first_block = text_to_bytes(' | ||
+ | cipher_bytes = block_encrypt(xor(first_block, | ||
+ | previous_block = cipher_bytes | ||
+ | |||
+ | for i in range(0, len(plain_bytes), | ||
+ | plain_block = plain_bytes[i: | ||
+ | key_index = (i+block_size) % len(key_bytes) | ||
+ | key_block = key_bytes[key_index: | ||
+ | if chaining: | ||
+ | plain_block = xor(plain_block, | ||
+ | cipher_block = block_encrypt(plain_block, | ||
+ | cipher_bytes += cipher_block | ||
+ | previous_block = cipher_block | ||
+ | | ||
+ | return cipher_bytes | ||
+ | |||
+ | def decrypt(cipher_bytes, | ||
+ | # ensure our key material is divisible by block_size | ||
+ | key_bytes = key_bytes * block_size | ||
+ | |||
+ | # the first block is thrown away | ||
+ | previous_block = cipher_bytes[0: | ||
+ | plain_bytes = [] | ||
+ | |||
+ | # The decrypted first block is ignored... | ||
+ | for i in range(block_size, | ||
+ | cipher_block = cipher_bytes[i: | ||
+ | key_index = i % len(key_bytes) | ||
+ | key_block = key_bytes[key_index: | ||
+ | plain_block = block_decrypt(cipher_block, | ||
+ | if chaining: | ||
+ | plain_block = xor(plain_block, | ||
+ | plain_bytes += plain_block | ||
+ | previous_block = cipher_block | ||
+ | return plain_bytes | ||
+ | |||
+ | |||
+ | def bytes_to_image(img_bytes, | ||
+ | as_np = np.asarray(img_bytes, | ||
+ | as_np = as_np.reshape(shape) | ||
+ | return as_np | ||
+ | |||
+ | # Play with different keys: | ||
+ | #key = " | ||
+ | key = " | ||
+ | key_bytes = binary_to_bytes(key) | ||
+ | #key_bytes = text_to_bytes(" | ||
+ | key_bytes = text_to_bytes(" | ||
+ | |||
+ | # Change between ECB and CBC modes: | ||
+ | chaining = False # False: ECB, True: CBC | ||
+ | |||
+ | img = cv.imread(' | ||
+ | img_bytes = img.tobytes() | ||
+ | |||
+ | img_encrypted = encrypt(img_bytes, | ||
+ | |||
+ | # We drop the first block as it's only used as initialization vector. | ||
+ | cv.imshow(" | ||
+ | cv.waitKey() | ||
+ | |||
+ | # Test if decryption works | ||
+ | # img_decrypted = decrypt(img_encrypted, | ||
+ | # cv.imshow(" | ||
+ | # cv.waitKey() | ||
+ | </ | ||
+ | |||
+ |