La somma di ciò che il client memorizza e ciò che il tuo server memorizza deve essere sufficiente per recuperare i dati segreti specifici dell'utente (ad esempio il token di accesso di Facebook). Ciò che il client memorizza è, principalmente, la password dell'utente (l'unica area di memorizzazione permanente sul lato client è il cervello dell'utente, se vogliamo consentire all'utente di utilizzare diverse macchine distinte a volontà). Se ho capito bene, non vuoi che il tuo server memorizzi i dati "così come sono": nel caso in cui il tuo server sia completamente compromesso, i segreti dell'utente dovrebbero essere comunque al sicuro (il più possibile).
Questo indica la crittografia basata su password . Dalla password dell'utente è derivata una chiave simmetrica K che viene utilizzata per crittografare simmetricamente un pacchetto che contiene i segreti dell'utente, ad es. l'account Facebook. Tecnicamente, sembrerebbe questo:
- Quando l'utente si registra, sceglie la sua password P e la invia al tuo server.
- Il tuo server genera un valore salt casuale S e calcola PBKDF2 su P e S , per produrre 256 bit di output T . Chiamiamo A i primi 128 bit di T e K l'altra metà a 128 bit.
- La prima metà ( A ) è memorizzata nel database del server; questo verrà utilizzato per autenticare gli utenti.
- La seconda metà ( K ) è non memorizzata; questa è la chiave simmetrica per quell'utente. I segreti dell'utente saranno crittografati con K .
- Quando l'utente effettua il login, invia il suo nome e P al tuo server (tramite HTTPS). Il tuo server recupera il sale S per quell'utente (come memorizzato nel suo database) e ricalcola T (usando P e S con PBKDF2). Se la prima metà del T ricalcolato corrisponde allo A memorizzato, l'utente viene autenticato e la seconda metà di T è K . Il server può quindi decodificare il pacchetto archiviato e accedere al token di accesso di Facebook.
Con questa configurazione, il server non memorizza (sul suo disco o nel suo database) il token di accesso di Facebook in chiaro, ma può accedervi quando l'utente effettua il login; spetta al server ricordare (in RAM) il token di accesso di Facebook finché ne ha bisogno.
Si noti che quando l'utente cambia la sua password, questo cambia anche K (il server deve anche generare un nuovo S , ma anche se il server erroneamente non lo ha fatto, K sarebbe ancora cambiato); pertanto, il server deve decrittografare il bundle memorizzato con il vecchio K e crittografarlo nuovamente con il nuovo K quando la password viene modificata. Questo non è difficile da integrare perché le interfacce di modifica della password richiedono di solito la vecchia password e la nuova password, quindi a quel punto il server ha entrambi.
Si noti inoltre che quando si dimentica la password, il pacchetto viene perso. Non c'è recupero per quel caso. Se l'utente dimentica la propria password, sarà necessario eseguire una reimpostazione della password, che è simile a una nuova registrazione; e un nuovo token di accesso a Facebook dovrà essere ottenuto.
In tutto quanto sopra, vediamo che il tuo server vede ancora la password dell'utente. Se il server è completamente compromesso e dirottato, l'utente malintenzionato sarà in grado di osservare le password degli utenti e i token di accesso di Facebook degli utenti per tutti gli utenti che effettuano l'accesso mentre l'attaccante controlla il server. Prevenire che è molto più difficile. Probabilmente, se il tuo server presenta solo un'interfaccia Web, dove tutte le "informazioni" sul lato client sono Javascript inviate dal tuo server, allora è impossibile fare meglio di ciò che fa lo schema sopra, in quel situazione.