Questo metodo di conferma della password rischia di compromettere l'integrità del file crittografato?

1

Sto cercando di creare uno script di crittografia / decrittografia di base per uso personale e funziona perfettamente. Sto postando questo nella sezione infosec perché la mia domanda ruota attorno a quanto sia facile rompere la crittografia.

NOTA: conosco poco la crittologia, quindi la domanda semplicistica.

Ecco un rapido mock-up del mio codice:

from Crypto.Cipher import AES
import hashlib
from random import randint
import struct
from getpass import getpass
import os

infile = sys.argv[1]
password = hashlib.sha256(getpass('[*] Enter Password: ')).digest()
ivector = ''.join(chr(randint(0, 0xFF)) for i in range(16))

encryptor = AES.new(password, AES.MODE_CBC, ivector)

with open(infile, 'rb') as infile:
    to_encrypt = infile.read()

to_encrypt += 'password_is_correct'
while len(to_encrypt)%16 != 0:
    to_encrypt += ' ' #Pad file to a multiple of 16 for encryption

encrypted = encryptor.encrypt(to_encrypt)
size = os.path.getsize(infile)
with open(infile, 'wb') as outfile:
    outfile.write(struct.pack(size, '<Q'))
    outfile.write(ivector)
    outfile.write(encrypted)

print '[*] Encryption Completed!'

Per riassumere. Questo codice crittograferà un file con un vettore di inizializzazione casuale e una password fornita dall'utente. Leggerà il file da crittografare e aggiungerà la stringa "password_is_correct" alla fine della stringa. Al momento della decodifica, il vettore di inizializzazione verrà letto dal file e verrà acquisita una password dall'utente. Se la password è corretta, la stringa "password_is_correct" dovrebbe essere nella stringa decrittografata. È un metodo valido una verifica della password? Questo rappresenta un qualche tipo di rischio per l'integrità del file per facilitare il processo di cracking dei file?

Il codice completo può essere trovato qui .

    
posta The Defalt 10.06.2016 - 08:37
fonte

2 risposte

4

Sì, questo è un metodo valido per la verifica della password.

Uno svantaggio è che un utente malintenzionato ora sa che il testo in chiaro "password_is_correct" corrisponde all'ultimo blocco nel testo cifrato. Fortunatamente, AES è non vulnerabile per testo in chiaro noto attacchi.

PGP anche verifica i dati decrittografati , ma utilizza proprietà di un blocco casuale invece di una stringa fissa. Un altro modo che viene spesso utilizzato in modo errato è verificare il riempimento del messaggio. Ciò può rendere possibile un riempimento di attacco oracle , sebbene ciò non si applichi alla tua situazione.

Un altro metodo tipico è memorizza un hash della chiave nel messaggio, in modo che la password possa essere verificata prima di decifrare il messaggio.

Ci sono altre cose che possono essere migliorate con il tuo script:

  • Utilizza SystemRandom per ottenere l'IV, poiché il random normale non è crittograficamente sicuro.
  • Utilizzare una funzione di derivazione chiave reale come PBKDF2 anziché SHA256 per ricavare la chiave di crittografia dalla password.
  • Archivia un HMAC del testo crittografato e verificalo prima della crittografia. CBC è vulnerabile a un attacco bit-flipping .
  • Puoi anche cifrare il campo di file.
risposta data 10.06.2016 - 09:42
fonte
-1

In pratica, ciò che stai facendo è derivare manualmente una chiave da una password e controllare manualmente l'integrità del file. La risposta standard a questo tipo di domanda è "non farlo". In breve, prova a utilizzare le librerie per eseguire sia la derivazione delle chiavi che la crittografia e i controlli di integrità. Password e file / file crittografato vanno in, file crittografato / file decifrato esce.

Integrità file

Il problema qui è che stai cercando di verificare la decrittografia corretta controllando che esista una stringa. Tuttavia, ciò che stai effettivamente controllando è solo la fine del file. Il problema è che il processo di crittografia non protegge dalla manipolazione del resto del file (crittografato). Il perché è un po 'complicato, ma fondamentalmente potrebbe essere possibile capovolgere in modo intelligente i bit nel file crittografato per cambiare l'output. Quindi il contenuto del tuo file "ABCpassword_is_correct" potrebbe diventare "AB D password_is_correct".

Dal momento che hai chiesto, questo potrebbe in alcuni casi influire in effetti anche sull'efficacia della riservatezza (la tua preoccupazione se qualcun altro può leggere il file senza la chiave). Se vuoi saperne di più ti consiglio di fare una domanda al riguardo su crypto , perché è strongmente correlato a come cripto effettivo funziona.

Verifica della password

Esiste un concetto in crittografia chiamato funzione di derivazione della chiave basata su password, che è probabilmente quello che stai cercando. C'è anche una libreria python che implementa questa funzionalità trovata qui . Se capisco correttamente che l'implementazione si sovrapponga a OpenSSL.

Alcuni contesti: PBKDF2 è un protocollo standardizzato (crittografico) che ti fornisce una chiave da un segreto. La parte più importante che fa oltre a ciò che hai scritto è l'aggiunta di un metodo salt al processo di password. Potresti chiedere perché è importante - il motivo principale è che potresti volere chiavi diverse per file diversi. Quindi, anche quando l'IV è lo stesso e parti dei file sono uguali, i tuoi file crittografati saranno indistinguibili. Dovrebbe essere sufficiente per usare il nome del file o il percorso come salt.

Altri problemi

Non sono sicuro se il processo di crittografia che stai utilizzando sia sicuro. Penso che tu abbia problemi simili con il padding. Idealmente useresti implementazioni standardizzate per quelli. Questo non solo evita bug (il recupero dei dati è difficile ...) ma assicura anche che la tua implementazione non indebolisca la tua sicurezza. La maggior parte dei problemi di sicurezza sono causati da una cattiva implementazione, e questo è anche il caso della crittografia.

    
risposta data 10.06.2016 - 08:55
fonte

Leggi altre domande sui tag