Cripta elementi con chiave singola o Usa KDF + sale per crittografare ogni elemento?

5

Attualmente sto pianificando lo sviluppo di un sistema in cui verranno archiviate informazioni estremamente sensibili per i singoli utenti. Attualmente sono in discussione due approcci. Per renderlo più concreto, diciamo che stiamo crittografando il numero di sicurezza sociale (SSN) di ciascun utente:

  1. Una volta, genera una chiave di crittografia globale / iv. Criptare ogni SSN nel database con la stessa chiave di crittografia / iv.
  2. Una volta, genera un segreto globale. Usa il segreto globale e un KDF (come PBKDF2 con un sale per utente) per generare una chiave univoca, iv pair per crittografare il SSN di ciascun utente.

Non ne so abbastanza per difendere in entrambi i modi, c'è qualche vantaggio per (2) su (1)?

EDIT: Sono principalmente alla ricerca di aiuto per valutare i pro ei contro di ogni approccio. Vale a dire (2) fornire ulteriore sicurezza rispetto a (1) dato che entrambi si basano su un segreto globale condiviso?

    
posta Eric Scrivner 19.04.2016 - 21:46
fonte

3 risposte

4

Riutilizzare una flebo è una cattiva idea. Ogni modalità di crittografia ha i propri requisiti sulla gestione IV, ma per la maggior parte di essi, le conseguenze del riutilizzo IV vanno dal problematico al mortale. Non farlo.

Il metodo "normale" consiste nell'utilizzare una singola chiave e un IV per record: ogni elemento crittografato riceverà la propria IV, che verrà archiviata lungo il risultato della crittografia. Generando sia la chiave che la IV da un segreto globale e un "sale" per-record di solito funziona (risulta in pseudocasuale IV, che va bene per la maggior parte delle modalità di crittografia) ma aggiunge complessità, che è, di per sé, una cosa negativa. p>

Effettuare correttamente la crittografia è un'arte difficile, soprattutto perché nella maggior parte dei contesti che garantiscono la crittografia, deve essere verificata anche l'integrità. La soluzione migliore sarebbe una modalità di crittografia autenticata - in pratica, GCM . GCM prende come input:

  • Una IV di dimensione nominalmente arbitraria, ma è raccomandata una IV di 12 byte.
  • Una chiave adatta per AES (128, 192 o 256 bit)
  • Il messaggio m per crittografare

L'output quindi consiste in c , la crittografia di m (con la stessa esatta dimensione) e t , il "tag di autenticazione" ", che ha le stesse dimensioni di un blocco AES (128 bit, ovvero 16 byte). Quello che devi poi memorizzare è l'IV, l'output criptato c e t .

Quando decodificano, il motore di decrittografia userà la IV e c , e produrrà t di nuovo, che dovrai confrontare con t per verificare le modifiche.

La cosa buona di GCM è che l'unico requisito per la versione IV è no riuse . Non è necessario rendere IV casuale o imprevedibile, ma NON DEVI riutilizzare lo stesso IV due volte. Potresti utilizzare un indicatore orario o un contatore o un indice di riga del database, a condizione di assicurarti di non riutilizzare mai un valore IV.

    
risposta data 20.04.2016 - 00:02
fonte
4

Data la proprietà dei SSN - essendo tutti garantiti per essere diversi - non c'è molto aggiunto in termini di sicurezza usando il secondo approccio, se usato modalità di funzionamento (che non hai divulgato) consente il riutilizzo IV.

Ma lascia che ti suggerisca una terza opzione: dovresti utilizzare un modulo di sicurezza hardware (HSM) per questo.

La tua domanda mi lascia l'impressione che tu stia cercando di risolverlo a livello programmatico, tuttavia c'è un grosso problema:

Se l'applicazione deve utilizzare gli SSN, è necessario che la chiave sia accessibile da qualche parte. L'encyption dell'SSN dovrebbe probabilmente essere implementato per mantenere i dati al sicuro nel caso in cui uno dei dischi rigidi o i dati memorizzati vengano trapelati.

Quando ciò accade e mantieni la tua chiave con i dati, non c'è più nulla che protegga i dati. Un dump di dati conterrà sicuramente anche la chiave, a meno che non venga utilizzato un HSM.

    
risposta data 19.04.2016 - 23:55
fonte
0

Una cosa che dovresti considerare è se questo valore è usato nelle clausole JOIN o GROUP BY nelle applicazioni che usano questi dati. Ad esempio, se le tue applicazioni hanno bisogno di assemblare una cronologia creditizia basata su SSN, vorresti che quel valore fosse deterministicamente crittografato in tutte le tue tabelle di database. L'alternativa sarebbe decodificare ogni record e quindi utilizzare il valore decrittografato come criterio JOIN, che sarebbe orribilmente inefficiente.

    
risposta data 26.04.2016 - 07:35
fonte

Leggi altre domande sui tag