Codifica dei file in modo sicuro utilizzando la password fornita dall'utente

2

Attualmente sto provando a creare (un certo tipo) editor di testo RTF sicuro, basato su desktop, scritto per node-webkit usando node.js. Sulla base di alcune risposte che ho letto qui, come ad esempio Come posso convertire in modo sicuro una password" stringa "su una chiave utilizzata in AES? e Consigliato # di iterazioni quando si utilizza PKBDF2-SHA256? , tra gli altri, ho trovato il seguente sistema. Tuttavia, sono piuttosto insicuro sul modo in cui ho combinato questi algoritmi e speravo che qualcuno potesse controllare il sistema.

Alla prima inizializzazione dell'applicazione:

  1. Genera 1024 byte pseudocasuali crittograficamente sicuri ( k )
  2. Genera 256 ulteriori ^ come sale ( s )
  3. Richiedi la password dell'utente ( p )
  4. Stira p usando PBKDF-2 usando s come sale, cicli di 64 KB (n = numero di cicli) a una lunghezza di 512 byte (lunghezza = l) ( P ) (richiede poco più di un secondo sul mio sistema)
  5. Encrypt k utilizzando AES-CBC con P come chiave ( K )
  6. Store s||n||l||K su disco

Per crittografare e quindi salvare un nuovo file:

  1. Richiedi la password dell'utente ( p )
  2. Leggi s||n||l||K dal disco
  3. Come nel passaggio 3 sopra, estrai p a P utilizzando s , n e l dal passaggio 2
  4. Decrypt K usando P
  5. Utilizza k per crittografare i dati dei file utilizzando AES CBC; salva su disco

Possibili dubbi (tenendo presente che questo dovrebbe essere utilizzabile su un laptop / desktop moderno) includono:

  • numeri magici (64 K, 512, 1024)
  • no IV (non sono sicuro se è necessario)
  • qualcosa su una combinazione di algoritmi
  • qualche altro stupido errore
posta Vivek Ghaisas 25.01.2015 - 00:12
fonte

1 risposta

5

Le mie osservazioni sono le seguenti:

  • La memorizzazione del valore di l è inutile. Dovresti invece memorizzare n . Dovresti sapere che PBKDF2 non produce sequenze diverse per valori diversi di l , ma piuttosto estende la sequenza più a lungo.
  • La generazione di 1024 byte per k e 512 byte per P sembra dispari, poiché AES non accetta più di una chiave a 256 bit (32 byte).
  • Nel passaggio 5 della crittografia, dici che k viene crittografato utilizzando AES-CBC, ma non menzionare come viene selezionato IV. Questo non è molto importante qui, dal momento che k non avrà blocchi duplicati, ma è buona pratica usare correttamente la modalità di crittografia.
  • Nel passaggio 5 della decifratura, si menziona nuovamente AES-CBC senza specificare IV. Questo è fondamentale: una selezione errata della IV può interrompere completamente il sistema.
  • Non fornisci autenticità sul file o sui metadati memorizzati. Questo è davvero importante, perché AES-CBC è malleabile (cioè il testo cifrato può essere modificato in modi che influenzano il testo in chiaro, senza bisogno di conoscere la chiave) e la tua costruzione potrebbe essere particolarmente suscettibile.

La tua struttura generale è effettivamente a posto, ma mancano i dettagli che separano una costruzione sicura da quella debole.

Ecco come lo farei io:

  • lascia p essere la password dell'utente.
  • lascia che k d (data key) sia un valore casuale a 128 bit.
  • lascia che s (salt) sia un casuale sia un valore casuale a 128 bit.
  • lascia c essere il conteggio delle iterazioni, ad es. 1.000.000.
  • lascia che k m (chiave principale) e k a (chiave di autenticazione) siano calcolati come due 16 byte (128 bit) metà di PBKDF2 (p, s, c, 32) , ovvero PBKDF2 della password utente e salt, con il numero di iterazioni definito e una lunghezza di output di 32 byte.
  • lascia k ' d (chiave dati crittografata) da calcolare come AES (k d , k m ) , utilizzando AES a 128 bit in modalità ECB.
  • lascia IV il vettore di inizializzazione da utilizzare durante la crittografia dei dati del file.
  • lascia Q (metadati) essere i valori concatenati s | c | k ' d | IV .
  • lascia a Q il record di autenticità per Q , definito come H (Q, k a ) , dove H è una funzione di hash crittografica in una costruzione HMAC, ad es. HMAC-SHA256.
  • memorizza Q e a Q nell'intestazione del file.

Poiché vengono utilizzate chiavi a 128 bit e AES ha una dimensione di blocco di 128 bit, è necessario crittografare solo un blocco quando si calcola k ' d e quindi AES in modalità ECB è sicuro; la complessità aggiuntiva dell'utilizzo di CBC o di un'altra modalità non è necessaria.

Fornire un record di autenticità per i metadati aiuta a impedire a un utente malintenzionato di "modificare" i parametri necessari per decodificare il file. Più in particolare, fornisce l'autenticità della IV, che è un obiettivo primario per la modifica, dato che l'aggiunta di un valore comporterà il primo blocco di testo in chiaro anch'esso sottoposto a tale valore su decrittazione. Questa proprietà è conosciuta come malleabilità. Per i plaintext parzialmente noti (ad esempio strutturati), ciò può avere effetti devastanti.

Dovresti essere in grado di estrapolare il resto del processo di crittografia e decrittografia dei file da qui. Un'aggiunta che vorrei fare è calcolare un hash HMAC dei dati crittografati, quindi memorizzarli nell'intestazione, per garantire l'autenticità dei dati crittografati.

    
risposta data 25.01.2015 - 01:02
fonte

Leggi altre domande sui tag