Crittografia dei file basata su password con un algoritmo di flusso sincrono più un algoritmo di hashing ad alta memoria?

1

Quindi questa è probabilmente una domanda stupida, ma sto cercando di capire perché non viene fatto quanto segue per i file a riposo crittografati tramite password:

  1. genera una chiave AES-256 / sale / iv
  2. prendi il messaggio in chiaro (ad esempio un file da 50 MB) e crittografalo con le credenziali del passaggio 1
  3. aggiungi le credenziali al messaggio crittografato
  4. consente all'utente di scegliere una password e convertirla in una chiave AES-256 utilizzando un metodo standard
  5. crittografare i risultati del passaggio 3 utilizzando la chiave del passaggio 4, utilizzando AES come crittografia a flusso sincrono con una forma modificata di modalità di feedback di uscita in cui:
    1. invece di usare il testo in chiaro per alimentare il prossimo blocco, una funzione di hashing di memoria elevata (come Argon2i) viene applicata al testo in chiaro, e i risultati di tale operazione vengono inseriti nel blocco successivo
    2. detta funzione di hashing utilizza parametri di costo coerenti derivati dalla dimensione dei dati in 3. (e quindi il numero di blocchi necessari), oltre alla quantità di memoria necessaria per decrittografare l'intero file (quindi il programma di crittografia ti conosce vuoi che richieda di scrivere un totale di 1 GB di memoria per decrittografare questo file)

A meno che AES-256 stesso non sia stato compromesso, sembrerebbe che per attaccare questo file, dovresti:

  1. scegli una probabile password e converti il corrispondente tasto AES-256
  2. usa questo tasto per decodificare l'intero file, ad ogni blocco calcolando l'hash Argon2i del blocco precedente (che richiede una quantità predeterminata di memoria)
  3. quando raggiungi la fine del file, usa i bit alla fine (che potrebbe essere la chiave che ti serve) per decodificare il primo blocco (già decrittografato una volta) e vedere se sei corretta

Dal momento che non è stato possibile parallelizzare facilmente il cracking a causa della cifratura a flusso sincrono (ogni tentativo richiede la decifrazione di messaggi completi), oltre al fatto che ogni blocco richiede di scrivere una quantità arbitraria di memoria (riducendo la minaccia di GPU veloci / futuri computer quantistici / ecc.), un metodo come questo non fornisce una sicurezza aggiuntiva in un modo che il passaggio da AES-256 a un AES-512 teorico non lo farebbe (dal momento che ogni password relativamente breve genererà comunque una chiave AES-512 completa, e puoi verificare se tale ipotesi è corretta senza decrittografare l'intero messaggio, quindi non c'è davvero nulla di guadagnato).

Regolando i parametri sulla tua funzione di hashing (in base alla dimensione del file), dovresti essere in grado di dire che "il tentativo di decodificare questo file da 1 KB richiede la scrittura di 500 MB di memoria ... e il tentativo di decifrare questo file da 3 GB richiederà anche la scrittura di 500 MB di memoria ". Quindi non sarebbe necessariamente proibitivo per i file di grandi dimensioni.

So che ci deve essere una ragione per cui non è stato fatto, e mi piacerebbe capire dove sto andando male!

    
posta atlantisnova 22.07.2017 - 00:23
fonte

1 risposta

1

Questo è semplicemente inutilmente complicato senza una vera ricompensa. La tua interposizione di Argon2 in modalità CFB lo rende più costoso, certo, ma i costi sono additivi , il che implica che sono associativi ( a + (b + c) = (a + b) + c ), il che significa che c'è niente da guadagnare eseguendo tutto quel lavoro in più con Argon2 in quel punto preciso -se stai semplicemente sfogliando i parametri di Argon2 al punto # che è altrettanto buono e semplice.

Quindi la tua idea non sembra migliore di:

  1. Genera una chiave di crittografia dei dati (DEK) casuale
  2. Per il messaggio in chiaro plaintext calcola un% co_de autenticato;
  3. Genera un% casualeciphertext = AEAD_encrypt(dek, plaintext);
  4. Genera una chiave di crittografia chiave (KEK) dalla password e sale: salt , fornendo i parametri costosi come vuoi per Argon2id;
  5. Cripta il DEK con KEK: kek = argon2id(password, salt, argon2_params) ;
  6. Scrivi encrypted_dek = AEAD_encrypt(kek, dek) come file crittografato.

Nota che:

  • Non hai davvero bisogno di IV / nonces casuali qui fintanto che fai molta attenzione a scegliere sempre un DEK casuale e salato ogni volta che cripti. La proprietà che si desidera garantire è che ogni chiave verrà sempre utilizzata per la crittografia di un solo messaggio.
  • Quando dico (salt, argon2_params, encrypted_dek, ciphertext) intendo uno schema crittografia autenticata che funziona con messaggi di lunghezza variabile. AES-GCM e ChaCha20 / Poly1305 sono due comuni e popolari in questi giorni. Non perdere tempo con le modalità e i MAC, usa qualcosa di precostruito.
  • Quando dico AEAD_encrypt e ciphertext intendo in un certo senso che incorpora il tag AEAD. Molte librerie emettono il tag di autenticazione separatamente da quello che chiamano il testo cifrato.
  • L'uso di un DEK e KEK separati ha la proprietà netta che è possibile modificare la password senza dover decifrare e ricodificare l'intero file; puoi semplicemente riavvolgere il DEK crittografato. Se non ti interessa, puoi semplicemente generare un DEK direttamente da Argon2.
  • Probabilmente dovresti usare Argon2id invece di Argon2i. O in realtà, attendi fino all'approvazione della RFC ...
risposta data 22.07.2017 - 01:08
fonte

Leggi altre domande sui tag