AES utilizzando chiavi derivate / IV. Introduce un punto debole?

9

Sto cercando un modo efficace per crittografare più campi in un database con AES utilizzando un'unica chiave globale, utilizzata in un'applicazione web di grandi dimensioni.

Ovviamente per riutilizzare questa chiave, è necessario un IV casuale casuale per ogni campo che deve essere crittografato.

Preferirei non introdurre più campi nel database per memorizzare ciascuno di questi IV, quindi l'approccio programmatico sembra essere quello di ricavare questi IV in qualche modo.

Sto giocando con l'utilizzo di entrambi:

key = sha256(global_key + table_name)
iv = sha256(column_name + primary_key)

O anche semplicemente:

key = global_key
iv = sha256(table_name + column_name + primary_key)

Sono propenso al primo a generare chiavi per tabella.

Ho già letto che gli IV non hanno bisogno di essere tenuti segreti. Quindi sto lavorando sul assunto che una chiave derivata o IV (anche se l'algoritmo diventa noto), non è più insicuro di qualsiasi altro IV non segreto, purché l'originale la chiave rimane segreta .

La domanda è:

C'è un difetto fatale nel mio approccio? Sto introducendo qualche serio punto debole che, nel caso in cui un avversario ottenga una copia del database, renderebbe più facile per loro recuperare i dati in testo semplice?

Comprendo che potenzialmente sollecitare una parola risposta.

Suggerimenti per schemi alternativi / migliori molto graditi, così come riferimenti a opere esistenti e come implementano scenari simili.

    
posta Leigh 13.11.2012 - 15:41
fonte

3 risposte

5

Un approccio potenzialmente migliore sarebbe archiviare la IV e il testo cifrato in una colonna. In questo modo, puoi generare IV nel modo più appropriato per la tua scelta della modalità di crittografia senza dover aggiungere colonne.

Qualcosa come "$AES-128-CBC$" + Base64.encode64(iv) + "$" + Base64.encode64(ciphertext) è simile al formato utilizzato in crypt , facilmente analizzabile, e la codifica Base64 è leggermente più comoda quando si eseguono query sul database utilizzando i client della riga di comando.

    
risposta data 13.11.2012 - 19:04
fonte
3

Il tuo approccio è insicuro. Se si modifica un valore nel database, verrà crittografato un nuovo valore utilizzando la stessa IV utilizzata per crittografare il valore precedente. (I dati verranno archiviati nello stesso posto, quindi il nome della tabella, il nome della colonna e la chiave primaria rimarranno invariati.) Ciò potrebbe compromettere la riservatezza. Il compromesso è particolarmente grave se si utilizza una codifica di streaming o AES-CTR o modalità simile, poiché in questo modo sono stati crittografati due valori diversi utilizzando lo stesso flusso, una vulnerabilità classica di riutilizzo dei keytream (il pad a due tempi è altamente insicuro) .

Invece, è meglio fare come altri raccomandano: genera un IV casuale e lo memorizza insieme al testo cifrato. In effetti, nella maggior parte dei modi operativi, puoi considerare l'IV come parte del testo cifrato.

    
risposta data 14.11.2012 - 09:12
fonte
2

Suppongo che tu stia utilizzando la modalità CBC ...

Vorrei sostenere che si tratta di una violazione di CWE-329 . L'IV può essere conosciuto per attaccare , ma deve essere casuale . Una soluzione più comune al tuo problema è solo quella di memorizzare un valore casuale molto sicuro e usarlo come "IV".

Diciamo che hai una tabella chiamata "segreto". L'autore dell'attacco ha una vulnerabilità di SQL Injection e vede questa tabella, può anche vedere che il valore corrente della chiave primaria. Calcolando un semplice hash sha256 è in grado di predire il prossimo IV o persino calcolare una tabella di future IV. (A seconda della piattaforma, la vulnerabilità di SQL Injection potrebbe essere trasformata in un oracolo di decrittografia! Nasty!)

Se dovessi creare questo, utilizzerei una funzione Key Derivation appropriata come PBKDF2. Queste sono funzioni più pesanti che rendono più difficile per l'attaccante calcolare il minerale o calcolare in massa. Non deve essere molto più pesante, ma il valore risultante deve avere le stesse dimensioni del codice.

Un'altra possibile soluzione è avere un "segreto IV" globale. Passa iv_secret + column_name + primary_key alla tua funzione di derivazione della chiave per produrre la tua IV. A causa dell'uso di un segreto, l'IV non è più un valore prevedibile e questa non è più una violazione di CWE-329. Inoltre, più questo valore è anche un nonce, non è probabile che lo stesso IV venga generato due volte per due valori diversi ... (A meno che non abbiate fatto un aggiornamento, che sarebbe una violazione). Per mitigarlo, puoi aggiungere un "numero di versione" o un timestamp dell'ultima modifica al calcolo IV.

    
risposta data 13.11.2012 - 17:11
fonte