Come memorizzare in modo sicuro i token bearer sul server?

5

Immagina di avere un servizio che implementa un flusso di OAuth 2.0 per consentire agli utenti finali di accedere ad app di terze parti e autorizzare tali app a utilizzare i dati del tuo servizio tramite alcune API.
Dopo aver autenticato con successo un'app di terze parti tramite il flusso OAuth, il servizio invia l'app di terze parti a un token al portatore che autentica (e autorizza) l'app di terze parti (a nome dell'utente finale) per utilizzare l'API del servizio.

Tale token al portatore deve essere memorizzato sui tuoi server, al fine di eseguire l'autenticazione per le chiamate API in arrivo. Poiché il token proprietario autentica (e autorizza) i client, è necessario archiviarlo in modo sicuro, come se si memorizzasse una password.
Tuttavia, mentre le password vengono salate + hash prima di salvarle su disco, vengono anche ricercate dal loro corrispondente principale (nome utente / indirizzo email), piuttosto che dalla rappresentazione sicura della password.

Nel caso di un token al portatore, non esiste un principio da utilizzare per cercare credenziali / token corrispondenti. Supponendo che desideri memorizzare token al portatore come le password (salted + hash), dovresti cercare ogni possibile sale, applicarli a ciascuno, quindi hash il token salato e quindi verificare se esiste in qualsiasi punto del tuo sistema. Quello non scala.

Quindi la mia domanda è: come puoi archiviare in modo sicuro i token bearer sul tuo server? Cioè, senza dover generare ogni possibile rappresentazione sicura di esso ogni volta che è necessario verificare un token.
Con "deposito sicuro di token bearer", intendo che un attaccante che ottiene il file di tutti i token bearer memorizzati in modo sicuro non sarà in grado di usarli.

    
posta derabbink 21.07.2015 - 23:10
fonte

2 risposte

2

Se le richieste provenienti dalla terza parte al provider OAuth hanno altri dati che associano la richiesta all'utente, ad esempio il nome o l'ID dell'utente, il server potrebbe memorizzare il token bearer come una normale password con singoli sali. Tuttavia, se le richieste di terze parti non contengono informazioni identificabili, il server può memorizzare una versione hash salata + del token al portatore con un valore di sale condiviso per tutti i token al portatore. Poiché i token OAuth scadono rapidamente, un sale unico non è altrettanto importante rispetto a una password che potrebbe non scadere mai. Se il token scade dopo 6-12 ore, l'utente malintenzionato non può crackare realisticamente l'hash e utilizzarlo per accedere a un account utente. Il server potrebbe quindi periodicamente ruotare il sale ogni settimana per una maggiore sicurezza.

    
risposta data 21.07.2015 - 23:45
fonte
1

Basato su risposta di Justin , sto costruendo il mio.

Se i token sono abbastanza lunghi (nel mio caso sono 200 caratteri alfanumerici ( [A-Za-z0-9] ), non c'è bisogno di saltarli. L'hashing da solo dovrebbe quindi essere sufficiente, dato che la complessità è abbastanza alta.

Se i token non sono abbastanza lunghi da farla franca solo con l'hashing (o se vuoi insistere per salarli), puoi modificare leggermente lo schema di generazione di token: Invece di generare un token casuale, genera anche un principal specifico per token. Quindi concatena i due e passa il risultato all'app consumer come un singolo token. Ciò richiede in sostanza ai client API di inviare anche le informazioni di identificazione dell'utente, ma è comodamente incorporato in un singolo token.

Internamente, salta + hash il token effettivo prima di archiviare e archivia separatamente l'entità specifica del token. Quando si verifica un token, si divide il token inviato in due, recuperando il token effettivo e il principal specifico del token. Questo principio può quindi essere utilizzato per cercare il token vero e salato + hash su cui è possibile eseguire un matcher.

Esempio concreto:

  1. Genera un token al portatore: ad es. %codice%
  2. Genera un principal specifico per token a lunghezza fissa: ad es. %codice%
  3. Genera un sale, ad es. %codice%
  4. Salt + hash il token al portatore ( a0z9B1Y8c2x7 ), che si tradurrebbe in qualcosa del genere: D3W6e4v5F5
  5. memorizza il token hash salato + accanto al principal specifico del token, cioè memorizza una tupla aabbccddeeff00112233445566778899
  6. Assegna all'utente la concatenazione del token e dell'elemento principale da trattare come token al portatore regolare: a0z9B1Y8c2x7
risposta data 24.07.2015 - 13:12
fonte

Leggi altre domande sui tag