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.