Attualmente sto scrivendo il mio piccolo gestore di password
Questo è il tuo primo errore. Qualcosa di così complesso ha molte insidie sottili in cui a volte cadono anche gli esperti, senza molta esperienza in questo settore non hai la possibilità di creare qualcosa di altrettanto vicino da proteggere.
conserva la chiave in un Hash SHA256
Uh oh ...
Questo non necessariamente indica che stai facendo qualcosa di sbagliato, ma ho forti dubbi che lo farai bene. Presumo tu stia parlando di una password principale sottoposta ad hashing qui? La password principale deve essere trasformata in una chiave utilizzando un KDF come PBKDF2, bcrypt o Argon2, quindi questa chiave viene utilizzata per crittografare le password memorizzate.
Se si desidera avere un modo per verificare che la password sia corretta, memorizzare un hash della chiave dovrebbe andare bene, ma NON DEVI memorizzare la chiave stessa ... se memorizzi la chiave chiunque abbia accesso alla tua memoria ha tutto ciò di cui ha bisogno per decrittografare tutte le password!
Se non stai parlando di hashing di una password principale e intendi una vera chiave generata casualmente, non ho idea di cosa stai cercando di ottenere qui , ma non dovresti usare un KDF lento con un gran numero di iterazioni.
In alternativa potresti eseguire l'hashing della password principale due volte, una per memorizzarla come hash per verificare successivamente che la password immessa dall'utente è corretto e di nuovo da utilizzare come chiave per la crittografia. A seconda di come viene fatto, potrebbe variare da un difetto di progettazione al dare completamente via la chiave.
Modifica: dopo aver visto il codice completo, sembra essere una quarta opzione: si memorizza un hash della password per in seguito controlla se la password inserita è corretta, quindi fai l'hash di questo hash da utilizzare come chiave, il che è dannoso quasi quanto memorizzare la chiave stessa.
I creare l'hash facendo quanto segue:
def sha256_rounds (raw, rounds = 100001): obj = hashlib.sha256 () for _ in xrange (rounds):
obj.update (raw) raw = obj.digest () return obj.digest ()
Non è proprio chiaro cosa sia raw
qui, ma presumo sia la password. Quello che stai facendo è un hash non salato usando SHA256. Non provare a creare il tuo KDF!
Dopo che è stato creato viene memorizzato con quanto segue:
key = base64.urlsafe_b64encode (provided_key) length = len (chiave) con open (key_file, "a +") come key_: front_salt, back_salt = os.urandom (16), os.urandom (16) key_.write ("{} {} {}: {}". format (front_salt, key, back_salt, length))
Quindi, stai creando la chiave hashing la password, quindi aggiungendo un sale davanti e dietro? Non solo la concatenazione di 2 diversi sali davanti e dietro non è standard, ma qui non si ottiene nulla perché viene eseguita dopo che il KDF è già terminato! Stai solo aggiungendo alcuni valori casuali per il gusto di averli lì.
Per mostrare quanto questo sia grave (come del commit 609fdb5ce976c7e5aa1832670505da60012b73bc), tutto ciò che serve per scaricare tutte le password memorizzate em> senza richiedere alcuna password principale è questo:
from encryption.aes_encryption import AESCipherfrom lib.settings import store_key, MAIN_DIR, DATABASE_FILE, display_formatted_list_outputfrom sql.sql import create_connection, select_all_dataconn, cursor = create_connection (DATABASE_FILE) display_formatted_list_output (select_all_data (cursor, "encrypted_data"), store_key (MAIN_DIR))
Sebbene provare a creare un gestore di password possa essere una buona esperienza di apprendimento, per favore non usarlo mai per qualcosa di lontanamente importante. Come suggerisce @Xenos, non sembra che tu abbia abbastanza esperienza che creare il tuo gestore di password sarebbe comunque davvero vantaggioso, sarebbe probabilmente un'opportunità di apprendimento migliore per dare un'occhiata a un gestore di password open source esistente.