Desidero proteggere alcuni dati altamente sensibili in un database. Ciò significherebbe che i dati devono essere crittografati e rimanere al sicuro per 100 anni se dovesse cadere nelle mani degli avversari. Voglio anche limitare la quantità di dati vulnerabili in testo normale alla volta nella RAM. Questo è così c'è meno possibilità che i dati in testo vengano paginati su disco. Inoltre, il database potrebbe essere abbastanza grande, quindi deve essere più efficiente della decodifica dell'intero database alla volta solo per accedervi. Pertanto sto pensando di crittografare i dati sensibili a livello di riga di un database. Ciò significherebbe un indice univoco che fa riferimento al record non crittografato, quindi ogni record può ancora essere trovato / recuperato, tuttavia i dati sensibili sono crittografati.
La mia soluzione sarebbe avere i dati per riga del database:
index | IV | sensitive encrypted data | MAC
- Una chiave di database a 256 bit verrà utilizzata per crittografare i dati sensibili che verranno generati utilizzando / dev / random.
- L'IV per ogni riga sarà 256 bit da / dev / urandom (più veloce di / dev / random).
- L'algoritmo di crittografia sarà Twofish.
- Il MAC di ogni record sarà HMAC-SHA3 dell'indice, IV e amp; dati sensibili usando il tasto.
Il sistema è singolo utente. L'utente creerà una passphrase alfanumerica strong (minimo 19 caratteri).
Una funzione di derivazione della chiave basata su password verrà eseguita sulla passphrase per creare una chiave di crittografia derivata che verrà quindi utilizzata per crittografare separatamente la chiave di database con Twofish. In questo modo l'utente può modificare la propria password senza dover crittografare nuovamente l'intero database: è sufficiente creare una nuova password e crittografare nuovamente la chiave del database. Capisco che questa sia la parte più debole dello schema, ma vorrei rendere molto difficile per un utente malintenzionato tentare tentativi di password. Penso che la sicurezza debba riposare nella forza della passphrase, poiché qualsiasi tipo di token secondario potrebbe essere compromesso contemporaneamente al dispositivo che contiene i dati crittografati (penso che il dispositivo e il token possano essere confiscati per ragioni arbitrarie) quando si passa attraverso la sicurezza dell'aeroporto, quindi sarebbe inutile).
- Per derivare la chiave dalla passphrase, PBKDF2 verrà utilizzato con 10.000 iterazioni usando HMAC-SHA3 con un'uscita a 256 bit e un massimo di 256 bit ottenuto da / dev / urandom.
- Quello che sto cercando di fare è bilanciare il numero di caratteri password necessari per rendere i dati sicuri rispetto a renderli ragionevolmente veloci per gli utenti su un dispositivo mobile che hanno processori lenti e memoria limitata. Non mi aspetto che l'utente attenda più di 5 secondi per il completamento del PBKDF.
- Viene creato un MAC utilizzando HMAC-SHA3-256 (chiave di crittografia derivata, sale | chiave di database crittografata) e memorizzato accanto alla chiave di database salt e crittografata sul disco. Questo può essere verificato al momento dell'accesso per assicurarsi che abbiano inserito la password corretta.
Quando il programma viene caricato, l'utente inserisce la passphrase. Esegue KDF, che genera la chiave per decrittografare la chiave di crittografia del database. La vera chiave di crittografia è quindi l'unica cosa conservata nella RAM mentre il programma è in esecuzione e utilizzata per verificare e decrittografare i singoli record del database quando richiesto.
- Qual è la lunghezza ottimale per il livello di fila IV? 256 bit vanno bene?
- La forza minima della password di 19 caratteri e 10.000 iterazioni di PBKDF2 è abbastanza strong da proteggere il database a 256 bit chiave? In caso contrario, quali parametri funzionerebbero?
- PBKDF2 è ancora un buon algoritmo ancora da utilizzare qui? In caso contrario, quali parametri di Scrypt?
- eventuali ulteriori modifiche o raccomandazioni per rendere sicuro il sistema?