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 [2025-03-30 08:21] – hof | gf_informatik:verschluesselung:symmetrisch [2025-04-01 11:46] (aktuell) – [Vorgehen] hof | ||
---|---|---|---|
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 51: | Zeile 51: | ||
{{ : | {{ : | ||
- | |||
### Herausforderung: | ### Herausforderung: | ||
Zeile 157: | 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() | ||
+ | </ | ||
+ | |||
+ |