Verschlüsselungsprogramm

Fragen zu Tkinter.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

› generiere_Schlüssel_entschlüsseln‹ und › generiere_Schlüssel_verschlüsseln‹ machen fast das selbe, bzw, die eine enthält die andere. Da sollte kein doppelter Code vorkommen.
Das Salz ist ja jetzt nur 16 Bytes lang. Wie kommst Du auf 32?
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

oh nein. ich probierte mal mit 32 bytes löschte aus versehen eine zeile machte diesen schritt rückgängig und das ging zu weit.
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Der Code funktioniert jetzt. Danke Für eure hilfe, besonders Sirius3 :) :) :D :D
Jetzt ist immer noch die frage wie ich den Hintergrund der Tabs auf Weiss umfärben kann. Wenn möglich auch die Farbe von ttk.Notebook
Sieh nämlich hässlich aus!
Vielen dank voraus.
LG Fire Spike
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Ich habe noch ein paar Fragen:
1. Tabhintergrundfarbe weiss
2. könnt ihr mir ein gutes beispiel mit threading zeigen? Ich will noch eine Forschrittsanzeige hinzufügen.
3. soll ich auf eine Klasse umsteigen?
4. ist die sicherheit der verschlüsselung gut?

Liebe Grüsse Fire Spike

Code: Alles auswählen

import base64
import os
import tkinter as tk
from tkinter import ttk
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

def generiere_Schlüssel_entschlüsseln(Passwort, salt):
    Passwort = Passwort.encode()
    kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                     length=32,
                     salt=salt,
                     iterations=1000000,
                     backend=default_backend()
                     )
    
    schlüssel = base64.urlsafe_b64encode(kdf.derive(Passwort))
    return schlüssel

def generiere_Schlüssel_verschlüsseln(Passwort):
    Passwort = Passwort.encode()
    salt = os.urandom(16)
    kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                     length=32,
                     salt=salt,
                     iterations=1000000,
                     backend=default_backend()
                     )
    
    schlüssel = base64.urlsafe_b64encode(kdf.derive(Passwort))
    return schlüssel, salt

def verschlüsseln(Passwort, Dateipfad):
    schlüssel, salt = generiere_Schlüssel_verschlüsseln(Passwort)
    f = Fernet(schlüssel)
    with open(Dateipfad, "rb") as Datei:
        with open(Dateipfad + ".verschluesselt", "wb") as Datei_verschlüsselt:
            Datei_verschlüsselt.write(salt + f.encrypt(Datei.read()))

def entschlüsseln(Passwort, Dateipfad):
    with open(Dateipfad, "rb") as Datei:
        salt = Datei.read(16)
        Dateiinhalt = Datei.read()
    schlüssel = generiere_Schlüssel_entschlüsseln(Passwort, salt)
    f = Fernet(schlüssel)
    Dateiname, Dateiendung = os.path.splitext(os.path.basename(Dateipfad))
    with open(os.path.join(os.path.dirname(Dateipfad), Dateiname + ".entschluesselt"), "wb") as Datei_entschlüsselt:
        Datei_entschlüsselt.write(f.decrypt(Dateiinhalt))
def main():
    root = tk.Tk()
    root.title("Dateien ent/verschlüsseln")
    root.config(bg="white")
    root_Tab = ttk.Notebook(root)
    Tab1 = ttk.Frame(root_Tab) 
    Tab2 = ttk.Frame(root_Tab)
    
    root_Tab.add (Tab1, text="Entschlüsseln")
    root_Tab.add (Tab2, text="Verschlüsseln")
    root_Tab.pack(expand=1, fill='both')
       
    Info1 = tk.Label(Tab1, text="Wichtig: Die Datei wird mit einer zusätzlichen\n Dateiendung gespeichert. Nicht überschrieben!\n", bg="white")
    Dateipfad_Text1 = tk.Label(Tab1, text="Bitte Dateipfad angeben", bg="white")
    Dateipfad_Eingabe1 = tk.Entry(Tab1, bg="white")
    Passwort_Text1 = tk.Label(Tab1, text="Bitte Passwort eingeben", bg="white")
    Passwort_Eingabe1 = tk.Entry(Tab1, bg="white")
    Entschlüsseln = tk.Button(Tab1, text="entschlüsseln", command=lambda: entschlüsseln(Passwort_Eingabe1.get(), Dateipfad_Eingabe1.get()), bg="white")
    Verschlüsseln = tk.Button(Tab2, text="verschlüsseln", command=lambda: verschlüsseln(Passwort_Eingabe2.get(), Dateipfad_Eingabe2.get()), bg="white")
    Info2 = tk.Label(Tab2, text="Wichtig: Die Datei wird mit einer zusätzlichen\n Dateiendung gespeichert. Nicht überschrieben!\n", bg="white")
    Dateipfad_Text2 = tk.Label(Tab2, text="Bitte Dateipfad angeben", bg="white")
    Dateipfad_Eingabe2 = tk.Entry(Tab2, bg="white")
    Passwort_Text2 = tk.Label(Tab2, text="Bitte Passwort eingeben", bg="white")
    Passwort_Eingabe2 = tk.Entry(Tab2, bg="white")

    Info1.grid(row=0, columnspan=1, sticky=tk.W)
    Dateipfad_Text1.grid(row=1, column=0, sticky=tk.W)
    Dateipfad_Eingabe1.grid(row=1, column=1, sticky=tk.W)
    Passwort_Text1.grid(row=2, column=0, sticky=tk.W)
    Passwort_Eingabe1.grid(row=2, column=1, sticky=tk.W)
    Info2.grid(row=0, columnspan=1, sticky=tk.W)
    Dateipfad_Text2.grid(row=1, column=0, sticky=tk.W)
    Dateipfad_Eingabe2.grid(row=1, column=1, sticky=tk.W)
    Passwort_Text2.grid(row=2, column=0, sticky=tk.W)
    Passwort_Eingabe2.grid(row=2, column=1, sticky=tk.W)
    Entschlüsseln.grid(row=4, columnspan=1, sticky=tk.W)
    Verschlüsseln.grid(row=4, columnspan=1, sticky=tk.W)
    root.mainloop()

if __name__ == "__main__":
    main()
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

›generiere_Schlüssel_entschlüsseln‹ und › generiere_Schlüssel_verschlüsseln‹ machen fast das selbe, bzw, die eine enthält die andere. Da sollte kein doppelter Code vorkommen. Die Variablennamen halten sich nicht an die Namenskonvention.
Warum muß man das immer duzende-male schreiben, und trotzdem ändert sich nichts daran?

Du benutzt anerkannte Verfahren zur Verschlüsselung, das ist also sicher.

Soll die Verschlüsselung im Hintergrund laufen, brauchst Du einen Thread, wie das geht, steht in der Dokumentation.
Soll der Thread mit der GUI kommunizieren, mußt Du erstens Blockweise verschlüsseln (ist eh besser, statt im Zweifel hunderte Megabytes in den Speicher zu laden), den Fortschritt in eine Queue schreiben und diese Queue von der GUI regelmäßig abfragen.

Du benutzt aber Fernet, das dafür gedacht ist, kurze Nachrichten zu verschlüsseln. Daher kann es kein blockweises Verschlüsseln. Dazu mußt Du Dich tiefer in die Thematik einlesen.
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Code: Alles auswählen

generiere_Schlüssel_entschlüsseln‹ und › generiere_Schlüssel_verschlüsseln‹ machen fast das selbe, bzw, die eine enthält die andere. Da sollte kein doppelter Code vorkommen. Die Variablennamen halten sich nicht an die Namenskonvention.
Warum muß man das immer duzende-male schreiben, und trotzdem ändert sich nichts daran?
Tut mir leid, ich wollte das nachdem der Code funktioniert machen. War nicht böse gemeint.
Ich weiss nicht wie ich die zwei funktionen in einander verpacken soll :roll: .
Für den Thread und das blockweise verschlüsseln werde ich mich einlesen.
Kannst du mir noch sagen wie ich den Hintergrund der Tabs auf weiss setzen kann?
Währe dir dankbar wenn du mir noch diese Frage beantworten würdest.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich benutze ttk nicht.

Was macht generiere_Schlüssel_verschlüsseln mehr als generiere_Schlüssel_entschlüsseln?
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Salz erstellen und salz zurückgeben
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann ist ja alles klar?
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

kann ich den Salz parameter optional festlegen?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Das wäre eine Möglichkeit.
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

was haltest du von einer "Stromchiffrenverschlüsselung"?
braucht fast kein speicher und ist mit einer for schleife umsetzbar.
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Ich hatte wie gesagt eine stromchffrenverschlüssellung vor, aber jetzt habe ich folgende probleme:
1. eine 28.3 kb grosse datei wird zu 2.8 mb gross und das ist relativ viel. Das liegt wahrscheinlich daran dass das Fernet immer noch zusätzliche daten speichert. wie kann ich das verhindern so das die daten nur ein einiges mal gespeichert werden?
2. wie kann ich die einzelnen bytes trennen? wenn frage 1 gelöst ist giebt es dieses problem nicht mehr!
Ich würde mich auf eine Antwort freuen. :D

Code: Alles auswählen

# Notizen
# --------
# hex in int = int('deadbeef', 16)
# --------
# Ende

import base64
import os
import tkinter as tk
from tkinter import ttk
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

# def generiere_Schlüssel_entschlüsseln(passwort, salt):
#     passwort = passwort.encode()
#     kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
#                      length=32,
#                      salt=salt,
#                      iterations=1000000,
#                      backend=default_backend()
#                      )
#     
#     schlüssel = base64.urlsafe_b64encode(kdf.derive(passwort))
#     return schlüssel
def generiere_Schlüssel(passwort, salt=False):
    passwort = passwort.encode()
    return_tuple = False
    if not salt:
        salt = os.urandom(16)
        return_tuple = True
        
    kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                     length=32,
                     salt=salt,
                     iterations=1000000,
                     backend=default_backend()
                     )
    
    schlüssel = base64.urlsafe_b64encode(kdf.derive(passwort))
    if return_tuple:
        return schlüssel, salt
    else:
        return schlüssel

def verschlüsseln(passwort, dateipfad):
    with open(dateipfad, "rb") as datei:
        with open(dateipfad + ".verschluesselt", "ab") as datei_verschlüsselt:
            schlüssel, salt = generiere_Schlüssel(passwort)
            f = Fernet(schlüssel)
            datei_verschlüsselt.write(salt)
            for i in range(os.path.getsize(dateipfad)):
                byte = datei.read(1)
                datei_verschlüsselt.write(f.encrypt(byte))

def entschlüsseln(passwort, dateipfad):
    dateiname, dateiendung = os.path.splitext(os.path.basename(dateipfad))
    with open(dateipfad, "rb") as datei:
        with open(os.path.join(os.path.dirname(dateipfad), dateiname + ".entschluesselt"), "ab") as datei_entschlüsselt:
            salt = datei.read(16)
            schlüssel = generiere_Schlüssel(passwort, salt)
            f = Fernet(schlüssel)
            for i in range(os.path.getsize(dateipfad) - 16):
                byte = datei.read(1)
                datei_entschlüsselt.write(f.decrypt(byte))
def main():
    root = tk.Tk()
    root.title("Dateien ent/verschlüsseln")
    root.config(bg="white")
    root_tab = ttk.Notebook(root)
    tab1 = ttk.Frame(root_tab) 
    tab2 = ttk.Frame(root_tab)
    
    root_tab.add (tab1, text="Entschlüsseln")
    root_tab.add (tab2, text="Verschlüsseln")
    root_tab.pack(expand=1, fill='both')
       
    info1 = tk.Label(tab1, text="Wichtig: Die Datei wird mit einer zusätzlichen\n Dateiendung gespeichert. Nicht überschrieben!\n", bg="white")
    dateipfad_text1 = tk.Label(tab1, text="Bitte Dateipfad angeben", bg="white")
    dateipfad_eingabe1 = tk.Entry(tab1, bg="white")
    passwort_text1 = tk.Label(tab1, text="Bitte Passwort eingeben", bg="white")
    passwort_eingabe1 = tk.Entry(tab1, bg="white")
    entschlüsseln_button = tk.Button(tab1, text="entschlüsseln", command=lambda: entschlüsseln(passwort_eingabe1.get(), dateipfad_eingabe1.get()), bg="white")
    verschlüsseln_button = tk.Button(tab2, text="verschlüsseln", command=lambda: verschlüsseln(passwort_eingabe2.get(), dateipfad_eingabe2.get()), bg="white")
    info2 = tk.Label(tab2, text="Wichtig: Die Datei wird mit einer zusätzlichen\n Dateiendung gespeichert. Nicht überschrieben!\n", bg="white")
    dateipfad_text2 = tk.Label(tab2, text="Bitte Dateipfad angeben", bg="white")
    dateipfad_eingabe2 = tk.Entry(tab2, bg="white")
    passwort_text2 = tk.Label(tab2, text="Bitte Passwort eingeben", bg="white")
    passwort_eingabe2 = tk.Entry(tab2, bg="white")

    info1.grid(row=0, columnspan=1, sticky=tk.W)
    dateipfad_text1.grid(row=1, column=0, sticky=tk.W)
    dateipfad_eingabe1.grid(row=1, column=1, sticky=tk.W)
    passwort_text1.grid(row=2, column=0, sticky=tk.W)
    passwort_eingabe1.grid(row=2, column=1, sticky=tk.W)
    info2.grid(row=0, columnspan=1, sticky=tk.W)
    dateipfad_text2.grid(row=1, column=0, sticky=tk.W)
    dateipfad_eingabe2.grid(row=1, column=1, sticky=tk.W)
    passwort_text2.grid(row=2, column=0, sticky=tk.W)
    passwort_eingabe2.grid(row=2, column=1, sticky=tk.W)
    entschlüsseln_button.grid(row=4, columnspan=1, sticky=tk.W)
    verschlüsseln_button.grid(row=4, columnspan=1, sticky=tk.W)
    root.mainloop()

if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Fire Spike: Du kannst da nicht sinnvoll eine Stromverschlüsselung draus machen. Du verschlüsselst jedes einzelne Byte als Fernet-Token, womit aus jedem Byte 480 Bytes werden, wenn ich mich jetzt nicht verrechnet habe.

Warum da bei Dir mehr heraus kommt, könnte vielleicht am falschen Dateimodus "ab" liegen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

wieso ist "ab" falsch? ich will ja bytes anhängen.
Und macht eine blockverschlüsselung mehr sinn? wenn ja wie kann ich das umsetzen?
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Fire Spike: Nein, Du willst keine Bytes anhängen, Du willst eine *neue* Datei erstellen.

Blockverschlüsselung macht Fernet bereits. Und das ist halt nicht für grosse Dateien gedacht, sondern für kleine bis mittelgrosse Nachrichten. Die als Text übermittelt/gespeichert werden sollen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

wie kann ich dann bytes anhängen?
wie kann ich denn dateien verschlüsseln die ein paar hundert mb bis 1gb gross sind?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Indem Du das, was Fenet macht, selbst nachprogrammierst.
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Nur so eine Frage: könntest du das? Wenn nein muss ich es gar nicht versuchen.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Die `encode` bzw. `decode`-Funktion von Fernet sind mit ihren Unterfunktionen nur eine Handvoll aufrufe anderer Crypto-Funktionen. Wenn Du verstehst, was diese Crypto-Funktionen machen, ist es kein großer Aufwand, das als Stream-Version nachzuprogrammieren.
Antworten