FEHLER BEI EINEM ONE TIME PAD

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
THE_PYTHON_GUY
User
Beiträge: 18
Registriert: Samstag 6. November 2021, 09:58

Hallo,
ich habe ein Skript erstellt was erst ein Bild ("test.jpg") verschlüsselt und einen Schlüssel abspeichert (das funktioniert)

Code: Alles auswählen

import os

filename = "test.jpg"

def encrypt(filename):
    to_encrypt = open(filename, "rb").read()
    size = len(to_encrypt)
    key = os.urandom(size)
    with open(filename + ".key", "wb")  as key_out:
        key_out.write(key)
        encrypted = bytes(a ^ b for (a, b) in zip(to_encrypt, key))
        with open(filename, "wb") as encrypted_out:
            encrypted_out.write(encrypted)

encrypt(filename)
das zweite Skript soll das Bild wieder mithilfe des KEYS entschlüsseln, aber es funktioniert nicht.

Code: Alles auswählen

import os

filename = "test.jpg"

def decrypt(filename, key):
    file = open(filename, "rb").read()
    key = open(key, "rb").read()
    decrypted = bytes(a ^ b for (a, b) in zip(file, key))
    with open("d_" + filename, "wb") as decrypted_out:
        decrypted_out.write(decrypted)

decrypt(filename, filename + ".key")

Was ist and dem CODE falsch?
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

was soll denn das '"d_"' in deiner 'with'-Anweisung?

Es wäre auch hilfreich wenn du die vollständige Fehlermeldung postest.

'os' nutzt man übrigens nicht mehr. Pfade erstellt man mit 'pathlib' und puzzelt sie nicht mit '+' zusammen. Wenn du Dateien öffnest, musst du sichergehen dass die wieder geschlossen werden.
Wieso nutzt du nicht überall 'with'? Das sorgt nämlich genau dafür.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

THE_PYTHON_GUY hat geschrieben: Samstag 6. November 2021, 10:03 Was ist and dem CODE falsch?
Also, ich denke es sollte funktionieren.
Wenn ich es ausprobiere wird jedenfalls das Original encrypted und beim decrypten wieder das Original mit dem "d_" erstellt.
Also wenn es bei dir nicht funktioniert, müsstest du mal beschreiben was genau nicht funktioniert.

Was ich aber komisch finde, ist dass, der key die gleiche Byte-Länge wie das Bild haben muss.
Unschön ist dass du unnötigerweise die key-Datei noch geöffnet hast, während auch die Bilddatei geöffnet ist. Außerdem schließt du nicht jedes mal die geöffneten Dateien.
Python vergibt das zwar manchmal, es ist aber nicht sauber. Daher sollte jede Dateioperation in einem with-Kontext laufen um das Schließen zu garantieren.
Ich würde den Code in mehrere Funktionen aufteilen, Lesen und Schreiben von Daten jeweils in getrennten Funktionen und getrennte Funktionen für Encryption und Decryption.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@rogerb: diese Art der Verschlüsselung mit one-time-Pads sieht genau das vor - der Schlüssel ist zufällig, und mindestens so lange wie der Klartext. Er muss vorher verteilt worden sein. Dann ist das Verfahren mathematisch beweisbar unknackbar. Die Verteilung ist aber natürlich das Problem.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@__deets__,

guter Hinweis! Dann nehme ich den Kommentar zurück :)
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Hm, also wenn ich erst das erste Skript und dann das zweite laufen lasse, dann stört sich Python an dem 'd_'.

Hab ich jetzt die Reihenfolge verwechselt? :?:

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 14077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Dennis89: Was meinst Du mit „es stört sich daran“? Syntaktisch ist es richtig. Und beim schreiben von Dateien sollte man sich den Dateinamen relativ frei aussuchen können. Jedenfalls sollte ein voranstellen von "d_" kein grundsätzliches Problem darstellen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Das Problem bei mir war die Pfadangabe von Windows und das flüchtige Code-überfliegen von mir.

Ich hatte das so stehen:

Code: Alles auswählen

filename = r"C:\Users/Dennis\Pictures\Pfennig.jpg"



def decrypt(filename, key):
    file = open(filename, "rb").read()
    key = open(key, "rb").read()
    decrypted = bytes(a ^ b for (a, b) in zip(file, key))
    with open("d_" + filename, "wb") as decrypted_out:
        decrypted_out.write(decrypted)

decrypt(filename,  filename + ".key")
und habe dann diesen Fehler erhalten:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\Dennis\AppData\Roaming\JetBrains\PyCharmCE2021.2\scratches\scratch_1.py", line 13, in <module>
    decrypt(filename,  filename + ".key")
  File "C:\Users\Dennis\AppData\Roaming\JetBrains\PyCharmCE2021.2\scratches\scratch_1.py", line 10, in decrypt
    with open("d_" + filename, "wb") as decrypted_out:
OSError: [Errno 22] Invalid argument: 'd_C:\\Users/Dennis\\Pictures\\Pfennig.jpg'
Gelöst habe ich dass dann mit 'pathlib' so:

Code: Alles auswählen

from pathlib import PureWindowsPath

filename = PureWindowsPath("C:/Users/Dennis/Pictures/Pfennig.jpg")


def decrypt(filename, key):
    file = open(filename, "rb").read()
    key = open(key, "rb").read()
    decrypted = bytes(a ^ b for (a, b) in zip(file, key))
    with open(filename.with_stem(f'd_{filename.stem}'), "wb") as decrypted_out:
        decrypted_out.write(decrypted)

decrypt(filename,  filename.parent / (filename.name + ".key"))
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 18278
Registriert: Sonntag 21. Oktober 2012, 17:20

PurePath ist falsch, da Du ja IO benutzen willst. Und da Du sogar noch einen PureWindowsPath benutzt hast, ist das Programm nur mit Windows nutzbar.
Du benutzt with_stem aber nicht with_name oder eigentlich with_suffix? Warum?
Path-Objekte mit open zu benutzen ist auch etwas unsinnig.

Code: Alles auswählen

from pathlib import Path

def decrypt(filename):
    data = filename.read_bytes()
    key = filename.with_suffix(filename.suffix + '.key').read_bytes()
    decrypted = bytes(a ^ b for (a, b) in zip(data, key))
    filename.with_name(f"d_{filename.name}").write_bytes(decrypted)

filename = Path("C:/Users/Dennis/Pictures/Pfennig.jpg")
decrypt(filename)
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Sirius3 hat geschrieben: Samstag 6. November 2021, 16:47 PurePath ist falsch, da Du ja IO benutzen willst. Und da Du sogar noch einen PureWindowsPath benutzt hast, ist das Programm nur mit Windows nutzbar.
Das Programm, das ich gepostet habe sollte keines Falls eine Lösung oder Verbesserung sein. Ich habe nur eine Möglichkeit gesucht, den Code des TE bei mir ohne Fehler auszuführen.
Sirius3 hat geschrieben: Samstag 6. November 2021, 16:47 Du benutzt with_stem aber nicht with_name oder eigentlich with_suffix? Warum?
'with_suffix' hatte ich drin, aber das hat mir 'jpg' durch 'key' ersetzt und nicht 'key' hinzugefügt. Dann bin ich gleich davon abgewichen. Mittlerweile weis ich, das ich mich bei dem Versuch verstrickt hatte. :roll:
Sirius3 hat geschrieben: Samstag 6. November 2021, 16:47 Path-Objekte mit open zu benutzen ist auch etwas unsinnig.
Hier habe ich jetzt bewusst das 'open' drin gelassen, weil ich den ursprünglichen Code nicht ändern wollte, sondern nur bei mir zu Testzwecken ausführen und einen eventuellen Fehler zu entdecken.

Zum Schluss, das hätte eigentlich an den Anfang gehört: Danke für deine Verbesserungsvorschläge. :!:

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten