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-04-01 08:11] – [Vorgehen] hof | gf_informatik:verschluesselung:symmetrisch [2026-04-02 20:20] (aktuell) – hof | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| ## Symmetrische Verschlüsselung | ## Symmetrische Verschlüsselung | ||
| + | < | ||
| Wir können nun beliebige Zeichenfolgen [[gf_informatik: | Wir können nun beliebige Zeichenfolgen [[gf_informatik: | ||
| Zeile 51: | Zeile 52: | ||
| {{ : | {{ : | ||
| + | |||
| ### Herausforderung: | ### Herausforderung: | ||
| Zeile 156: | Zeile 158: | ||
| </ | </ | ||
| ++++ | ++++ | ||
| + | |||
| ### Verkettung ausprobieren | ### Verkettung ausprobieren | ||
| Zeile 162: | Zeile 165: | ||
| * Was passiert mit anderen (längeren) Schlüsseln? | * Was passiert mit anderen (längeren) Schlüsseln? | ||
| * Warum ist ein Schlüssel nur aus Grossbuchstaben ungünstig? | * Warum ist ein Schlüssel nur aus Grossbuchstaben ungünstig? | ||
| + | |||
| + | |||
| #### Vorgehen | #### Vorgehen | ||
| Zeile 172: | Zeile 177: | ||
| * Dokumentiere die Resultate in OneNote / Word / Latex / Jupyter. | * Dokumentiere die Resultate in OneNote / Word / Latex / Jupyter. | ||
| - | <code python | + | <html>< |
| + | # In normal | ||
| + | import micropip | ||
| + | await micropip.install([" | ||
| import cv2 as cv | import cv2 as cv | ||
| import numpy as np | import numpy as np | ||
| Zeile 195: | Zeile 204: | ||
| def binary_to_bytes(binstring): | def binary_to_bytes(binstring): | ||
| + | """ | ||
| binstring *= 8 # ensure we are byte-aligned | binstring *= 8 # ensure we are byte-aligned | ||
| result = [] | result = [] | ||
| Zeile 217: | Zeile 227: | ||
| def encrypt(plain_bytes, | def encrypt(plain_bytes, | ||
| + | """ | ||
| + | * chaining=True: | ||
| + | * chaining=False: | ||
| + | The returned ciphertext starts with the IV block. | ||
| + | """ | ||
| # random initialization vector | # random initialization vector | ||
| - | iv = random.randbytes(block_size) | + | iv = list(random.randbytes(block_size)) |
| # ensure our key material is divisible by block_size | # ensure our key material is divisible by block_size | ||
| key_bytes = key_bytes * block_size | key_bytes = key_bytes * block_size | ||
| - | | + | |
| - | cipher_bytes = block_encrypt(xor(first_block, | + | cipher_bytes = iv |
| - | previous_block = cipher_bytes | + | |
| for i in range(0, len(plain_bytes), | for i in range(0, len(plain_bytes), | ||
| plain_block = plain_bytes[i: | plain_block = plain_bytes[i: | ||
| - | key_index = (i+block_size) | + | key_index = i % len(key_bytes) |
| key_block = key_bytes[key_index: | key_block = key_bytes[key_index: | ||
| if chaining: | if chaining: | ||
| Zeile 240: | Zeile 254: | ||
| def decrypt(cipher_bytes, | def decrypt(cipher_bytes, | ||
| + | """ | ||
| + | * chaining=True: | ||
| + | * chaining=False: | ||
| + | The ciphertext is expected to start with the IV block, even in ECB mode. | ||
| + | """ | ||
| + | |||
| # ensure our key material is divisible by block_size | # ensure our key material is divisible by block_size | ||
| key_bytes = key_bytes * block_size | key_bytes = key_bytes * block_size | ||
| - | # the first block is thrown away | + | # recover |
| previous_block = cipher_bytes[0: | previous_block = cipher_bytes[0: | ||
| plain_bytes = [] | plain_bytes = [] | ||
| Zeile 250: | Zeile 270: | ||
| for i in range(block_size, | for i in range(block_size, | ||
| cipher_block = cipher_bytes[i: | cipher_block = cipher_bytes[i: | ||
| - | key_index = i % len(key_bytes) | + | key_index = (i-block_size) |
| key_block = key_bytes[key_index: | key_block = key_bytes[key_index: | ||
| plain_block = block_decrypt(cipher_block, | plain_block = block_decrypt(cipher_block, | ||
| Zeile 265: | Zeile 285: | ||
| return as_np | return as_np | ||
| - | # Play with different keys | + | # Play with different keys: |
| - | key = " | + | #key = " |
| key = " | key = " | ||
| key_bytes = binary_to_bytes(key) | key_bytes = binary_to_bytes(key) | ||
| - | key_bytes = text_to_bytes(" | + | #key_bytes = text_to_bytes(" |
| key_bytes = text_to_bytes(" | key_bytes = text_to_bytes(" | ||
| - | # Change between ECB and CBC modes | + | # Change between ECB and CBC modes: |
| chaining = False # False: ECB, True: CBC | chaining = False # False: ECB, True: CBC | ||
| - | img = cv.imread(' | + | img_url |
| + | # In vanilla python, use urllib.request.urlopen(img_url) | ||
| + | from pyodide.http import pyfetch | ||
| + | response = await pyfetch(img_url) | ||
| + | data = await response.bytes() | ||
| + | arr = np.asarray(bytearray(data), | ||
| + | img = cv.imdecode(arr, | ||
| img_bytes = img.tobytes() | img_bytes = img.tobytes() | ||
| img_encrypted = encrypt(img_bytes, | img_encrypted = encrypt(img_bytes, | ||
| - | # We drop the first block as it only used as initialization vector. | + | # We drop the first block as it' |
| cv.imshow(" | cv.imshow(" | ||
| - | img_decrypted = decrypt(img_encrypted, | ||
| cv.waitKey() | cv.waitKey() | ||
| # Test if decryption works | # Test if decryption works | ||
| + | # img_decrypted = decrypt(img_encrypted, | ||
| # cv.imshow(" | # cv.imshow(" | ||
| # cv.waitKey() | # cv.waitKey() | ||
| - | </code> | + | </bottom-editor></ |