Best practice per la memorizzazione sicura dei token di accesso

17

Quali sarebbero le migliori pratiche per l'archiviazione di token di accesso di un'altra API per i tuoi utenti? In particolare sto sviluppando un'applicazione con alcuni amici che consente all'utente di accedere a Facebook per autenticarsi entrambi nella propria API REST interna e renderla in grado di recuperare i propri amici (e altre cose).

Stavo pensando di generare una chiave e usarla per crittografare il token di accesso a lungo termine per l'account Facebook dell'utente e possibilmente altre informazioni sensibili. Come schema di crittografia, utilizzerei AES-256-CBC e la chiave sarebbe stata inviata al client, che la tiene (e la aggiorna di tanto in tanto). Ma se genero quella chiave con qualsiasi casualità al suo interno, l'utente può usare solo un client. Come gli altri client avrebbero bisogno di quella chiave per decodificare il token di accesso di Facebook e altri dati. Una soluzione potrebbe generare la chiave da qualcosa di unico durante il log-in di Facebook, ma purtroppo l'unica cosa che posso trovare è l'userid, che ho bisogno di trovare il record dell'utente nel database.

Ci sono molti argomenti su questo sullo stackoverflow, ma niente risponde a quello che voglio. Quello che voglio veramente è criptare il token di accesso di Facebook e altri dati usando una chiave che solo il lato client conosce. La creazione di quelle chiavi dovrebbe essere possibile solo quando l'utente si autentica usando il sdk di Facebook o quando viene fornita la chiave attuale.

Qualche idea?

    
posta Joren Van Severen 04.09.2013 - 14:11
fonte

3 risposte

8

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.

    
risposta data 04.09.2013 - 16:27
fonte
2

Ero alla 10a conferenza ISC di sicurezza e crittologia la scorsa settimana e lì Ho visto qualcuno proporre un metodo per memorizzare i token di passaggio utente utilizzando la Rete neurale . Ha creato un NN che impara i token di passaggio utente e si è aggiornato utilizzando un metodo di apprendimento NN veloce. È un nuovo metodo e promette sicurezza, ma richiede molta attenzione all'apprendimento.

Aggiorna

Il documento era in Farsi intitolato significa User Access Control Using Neural Network and chaotic system

(lo stack non supporta i caratteri Farsi! Ho usato l'immagine invece !!!)

    
risposta data 04.09.2013 - 15:25
fonte
2
risposta data 17.02.2014 - 21:03
fonte

Leggi altre domande sui tag