Un buon metodo per archiviare i contenuti utente crittografati senza memorizzare la chiave dell'utente in testo semplice?

1

Ho un numero di requisiti apparentemente contraddittori:

1) Otteniamo contenuti per utenti di terze parti; i contenuti per determinati utenti devono essere archiviati crittografati a riposo per motivi di conformità

2) L'utente dovrebbe essere in grado di decrittografare e visualizzare i propri contenuti tramite una webapp / api protetta

3) Ci sono molti utenti su un determinato account, e tutti dovrebbero essere in grado di decrittografare e visualizzare i reciproci contenuti (implicando una chiave condivisa)

4) Un processo di lavoro di back-end dovrebbe essere in grado di decodificare e rielaborare il contenuto dell'utente in qualsiasi momento, se vogliamo (ad esempio) migliorare la nostra analisi

Se dovessimo, potremmo sacrificare il n. 4 (o forse chiedere all'autore di autorizzarlo).

Naturalmente non voglio archiviare la chiave di crittografia in testo normale ovunque. Sarebbe molto più conveniente archiviarlo a livello di utente, crittografato da un hash PBKDF2'ed dalla propria password - ma questo introduce un flusso di lavoro ingombrante se dimentica la password e deve ripristinarla (dato che ora non è più possibile derivare la chiave .)

Non posso neanche usare la password, perché l'accesso al contenuto già crittografato dovrebbe sopravvivere alle richieste di modifica delle password. Inoltre, ovviamente non abbiamo accesso alla password in chiaro nei processi di lavoro back-end asincroni.

C'è un modo generalmente accettato di farlo? Per esempio. potrei usare un qualche tipo di flusso di lavoro 2FA-ish per recuperare un utente segreto che non immagazzino mai localmente, ma che è usato per proteggere la chiave?

    
posta fridgepolice 08.02.2017 - 23:58
fonte

2 risposte

3

L'approccio abituale consiste nell'utilizzare una chiave principale per ciascun account che esegue il controllo effettivo di crittografia / decrittografia / integrità, ma che non viene mai memorizzato in testo normale da nessuna parte. Questa chiave master dovrebbe essere generata utilizzando un generatore di numeri casuali sicuro e non ci dovrebbe essere alcun modo per recuperare il suo valore di testo normale.

Cifra la chiave master con le chiavi per utente derivate dalle credenziali dell'utente (puoi utilizzare una funzione di derivazione della chiave - utilizzare qualcosa di più strong di PBKDF2 se possibile, come scrypt o argon2 - sulla password dell'utente, o richiedere all'utente avere un altro tipo di chiave crittografica come un certificato client TLS). Ogni utente memorizza quindi la propria copia crittografata della chiave master per il proprio account. Queste chiavi master crittografate possono essere archiviate sul server, perché sono inutili senza le chiavi per utente per decrittografarle. Le chiavi per utente non vengono mai memorizzate sul server in alcuna forma; sono forniti direttamente dal cliente o derivati effimeri dai dati forniti dal cliente (come una password), utilizzati e quindi cancellati.

Se necessario (per il tuo n. 4) puoi anche crittografare la chiave master di ciascun account con altre chiavi, ad esempio per il tuo processo in background. Certo, allora hai appena superato il primo passo; dov'è la chiave / credenziale-che-genera-una-chiave memorizzata per quel lavoratore? In che modo è protetto in modo tale che un utente malintenzionato non possa semplicemente prenderlo, decrittografare le chiavi principali corrispondenti e andare in città?

Il reset della password diventa alquanto complicato. Cambiare semplicemente una password è semplice: recupera la vecchia password, decrittografa la chiave master, la crittografa nuovamente con la nuova password e salva la chiave master appena criptata nel database. Reimpostare una password quando la vecchia è sconosciuta è più difficile. Le solite opzioni lì (a parte "non puoi, non senza perdere tutti i tuoi dati crittografati", che presumo inaccettabile) sono di dare all'utente le chiavi di ripristino usa una sola volta che sono molto utili troppo lungo da utilizzare per le normali password ma può essere utilizzato per decrittografare la master key quando necessario (il che significa che si avrà una versione della chiave master crittografata con la chiave standard per utente e una con la chiave di ripristino dell'utente), e richiedere uno di quelli per la reimpostazione della password o richiedere che un altro utente autorizzato ad accedere a tali dati sia autorizzato per l'utente che reimposta la propria password e utilizzare le credenziali dell'utente di sblocco per sbloccare la copia della chiave master dell'utente, quindi crittografare con la chiave dell'utente di reset e memorizza quella chiave master appena criptata (dato che hai più utenti per "account", questo funzionerebbe abbastanza bene fino a quando nessun account non avrà tutti dimenticato le loro password allo stesso tempo).

    
risposta data 09.02.2017 - 01:53
fonte
1

Che ne dici di un servizio / demone di crittografia dedicato in esecuzione sul tuo server web?

Il servizio richiederebbe una password principale (nota a voi) e avrebbe bisogno di essere reinserito al riavvio del server. È possibile utilizzare una funzione di derivazione della chiave per creare una chiave di crittografia in memoria.

I dati possono essere quindi crittografati o decodificati a piacimento dal servizio che viene utilizzato dall'app Web e dal processo di back office worker.

    
risposta data 09.02.2017 - 01:49
fonte

Leggi altre domande sui tag