it-swarm.dev

Va bene che il segreto API sia archiviato in testo normale o sia in grado di decrittografarlo?

Non sono API keys considerato nomi utente e API secrets considerate password? Perché i server API come Amazon Web Services ti consentono di visualizzare il tuo segreto API in testo semplice? Mi fa pensare che lo memorizzino in testo semplice o almeno in un formato decodificabile.

Non è meglio se i segreti dell'API sono stati trattati come password che dovresti digitare per creare e poi hash nel database invece di essere consegnato in testo normale? Se per qualche motivo il loro database segreto dell'API fosse compromesso, aprirà facilmente le porte di inondazione per molte applicazioni che utilizzano la loro API. Tuttavia, se è stato sottoposto a hash in un modo non decodificabile, non tutto è facilmente perdibile.

36
IMB

No. Le chiavi API devono essere archiviate in chiaro.

Non sono password: sono chiavi crittografiche. Queste chiavi sono usate per cose come l'autenticazione delle richieste (usando SHA1-HMAC). Il server deve conoscere la chiave crittografica per applicare gli algoritmi crittografici.

Pertanto, la chiave API deve essere memorizzata in chiaro sul server. Se il server memorizzava solo un hash della chiave API, non poteva verificare l'autenticità dei messaggi dal client o autenticare i messaggi inviati al client.

17
D.W.

L'hashing non è memoria; distrugge irreversibilmente i dati. Possiamo evitare di chiamare l'hash della password come "memorizzazione della password" perché quando abbiamo effettivamente bisogno della password, abbiamo un operatore umano a portata di mano per digitarla. In effetti, quando abbiamo la password non memorizziamo la password, ma solo un token sufficiente per verificare la password digitata.

Una chiave API deve essere archiviata in modo tale da poter essere riutilizzata in modo incustodito . Il server deve davvero store esso, invece di ricordarsene solo un fantasma, perché ha bisogno della chiave autentica per accedere all'API.

13
Tom Leek

Sebbene sia più sicuro eseguire l'hashing dei token API, presenta un problema di usabilità: i token sono lunghi e casuali e dovrebbero essere comunicati all'utente solo una volta prima dell'hash. Questo rende un po 'difficile proteggerli con un hash.

Il mio suggerimento per uno scenario sicuro sarebbe il seguente:

  1. Generare un valore casuale salt e memorizzarlo nel database. Questo salt non deve essere uguale alla password dell'utente salt.
  2. Prendi la password in chiaro dell'utente e calcola KDF(password, salt), dove KDF è una funzione di derivazione della chiave come bcrypt. Chiama il valore risultante k.
  3. Genera una chiave API.
  4. Crittografa il valore della chiave API con AES, usando k come chiave e memorizza il testo cifrato nel database.
  5. Elimina la chiave API in testo normale e k.

Quando l'utente accede, la webapp conosce la propria password e la utilizza per calcolare k, che viene quindi utilizzata per decrittografare la chiave API e visualizzarla.

Quando l'utente desidera utilizzare l'API, deve inviare k nonché la chiave API in testo normale, tramite SSL. La webapp può quindi decrittografare il valore della chiave API memorizzata utilizzando k e confrontarlo con la chiave API fornita. Se corrispondono, è valido. Ciò consente l'utilizzo della chiave API senza che l'app debba archiviare la password dell'utente.

Se un utente malintenzionato viola il database, è necessario decifrare la password dell'utente per calcolare k.

9
Polynomial

Sembra che ci sia un po 'di confusione qui e altri posti , quindi sto aggiungendo questa risposta nella speranza che chiarisca la situazione per gli altri utenti.

Esistono due tipi di segreti API che potrebbero essere utilizzati.

Il caso d'uso di cui tratta la maggior parte delle risposte in questa pagina è una chiave segreta che viene utilizzata per firmare e verificare i messaggi usando un algoritmo come HMAC. In questo caso, sia il client che l'API necessitano del valore effettivo della chiave per creare una firma del messaggio. Il server confronta quindi la firma che ha generato con la firma inviata dal client ed è in grado di verificare il messaggio. Come accennato in precedenza, se la chiave originale non è riproducibile sul server, ciò non può funzionare. Dopo aver inizialmente condiviso la chiave con il client (su un canale crittografato) non è più necessario trasmettere la chiave tra client e server.

L'altro segreto client API comune è semplicemente una credenziale segreta (come potresti vedere in una tipica richiesta di token di accesso OAuth2). Questa credenziale viene trasmessa su ogni richiesta e pertanto deve essere trasmessa solo su un canale crittografato (come HTTPS). In questo caso, il server deve conservare solo informazioni sufficienti per verificare che il valore segreto fornito dal client sia corretto, quindi il segreto può e deve essere sottoposto a hash. In questo caso, il segreto agisce efficacemente come password, quindi è necessario prendere le stesse precauzioni.

Dichiarazione di non responsabilità: non sono un ricercatore di sicurezza e dovresti assolutamente fare ulteriori ricerche su questo e qualsiasi argomento prima di seguire ciecamente qualsiasi consiglio su questo StackExchange.

tl; dr L'asporto più importante è che diverse API possono usare il segreto in diversi modi. È importante capire come la tua API sta usando il segreto client per valutare le migliori pratiche per la sua memorizzazione.

8
Nick Sloan

Inserendo i miei due centesimi a causa di un problema che non è stato ancora menzionato. In particolare, sono d'accordo con quanto ha detto @NickSloan, ma con un altro avvertimento.

C'è un'altra differenza importante tra una chiave API e una password. Le chiavi API sono uniche per il tuo sito. La parte che rende la sicurezza della password così critica è la condivisione della password. Se qualcuno ottiene una password salvata da un utente sul tuo sito, non è solo il tuo sito ad essere compromesso: è ogni altro sito a cui l'utente ha usato quella password (e-mail/nome utente). Molte persone riutilizzano le password attraverso siti critici: banche, social media, e-mail, ecc. Ciò significa che una buona sicurezza delle password non riguarda tanto la protezione dell'accesso al tuo sito quanto la protezione dei tuoi utenti su altri siti. Non possiamo costringere gli utenti a migliorare la sicurezza, quindi dobbiamo assumerci il peggio e adottare ulteriori misure per proteggere la propria privacy.

Una chiave API è uno scenario completamente diverso perché è unico per il tuo sito. Di conseguenza, se viene rubato, l'attaccante ottiene l'accesso al tuo sito, ma non ottiene nulla che possa sfruttare contro la banca/e-mail/ecc. Di quella persona. Ciò significa che il livello di rischio per le chiavi API è effettivamente inferiore a quello per le password. Non si trovano nello stesso parco palla: le chiavi API sono più simili agli identificatori di sessione che alle password.

Comprendere che questi sono più simili agli identificatori di sessione che alle password fornisce alcune informazioni pratiche su come proteggere adeguatamente tali chiavi. Si noti che la seguente discussione è applicabile alle chiavi API per cose come OAuth e non credenziali di crittografia (come discusso da @NickSloan nella sua risposta).

Le maggiori minacce alle password sono gli attacchi di phishing e i database compromessi, motivo per cui li memorizziamo con hash nei nostri database. Le maggiori minacce alle chiavi API sono le stesse delle chiavi di sessione: punti deboli nelle applicazioni front-end come vulnerabilità XSS, MIM e simili. È importante notare che l'applicazione front-end ha bisogno della password in forma non crittografata, quindi l'hashing della chiave API non ti guadagna davvero nulla quando la persona che ha più probabilità di averla rubata ne ha bisogno in testo semplice.

Invece, proteggi un identificatore di sessione (o OAuth o chiave API specifica del client) principalmente tenendo traccia del client. Se un identificatore di sessione viene rubato tramite XSS o altri mezzi dal client , un risultato tipico è che quell'identificatore deve essere utilizzato dall'aggressore su un nuovo dispositivo. Ciò significa che all'improvviso vedrai una vecchia chiave arrivare con un nuovo agente utente. Tale modifica è facile da rilevare e correggere: invalidare immediatamente tutte le chiavi API. Soprattutto nel caso di OAuth richieste, questo è molto indolore per l'utente: si limitano ad accedere e ne ottengono immediatamente uno nuovo, mentre qualcuno che ha solo rubato la chiave (e non ha la password) è tornato al tavolo da disegno.

Questa è una misura di difesa abbastanza comune che un hacker più intelligente proverà anche a registrare l'agente utente associato alla chiave rubata e ad usarlo in tutte le richieste future, ma puoi ancora vedere facilmente qualcosa di sospetto quando lo stesso utente ha richieste in arrivo da più indirizzi IP. Come ogni altra cosa al mondo, questo può essere un po 'un gioco di gatto e topo, ma ci sono alcuni aspetti importanti:

  1. Una chiave API/token OAuth/ID sessione è in realtà solo un modo per ricordare un utente su un determinato dispositivo, quindi non è necessario inserire la password in ogni pagina. Di conseguenza, in caso di dubbio, è possibile semplicemente eliminare tutte le chiavi autorizzate e forzare l'utente a riconnettersi.
  2. In tutti e tre i casi, poiché la perdita di chiave/token/ID comporta la compromissione di un account, è importante disporre di un po 'di sicurezza attiva attorno a queste cose e rilevare/rispondere se accade qualcosa di sospetto. Se hai mai ricevuto notifiche da Facebook/Google/etc su qualcuno che tenta di accedere al tuo account dal Messico, è perché un ragazzo della sicurezza da qualche parte sta facendo il proprio lavoro nel modo giusto.
  3. I vettori di attacco principali per chiavi/token/ID sono diversi da quelli delle password. Potresti comunque volerle hash nel tuo database (di nuovo, non stiamo parlando di credenziali di crittografia che devono essere in testo normale), ma non puoi semplicemente cancellarle nel tuo database e definirti sicuro. È necessario assicurarsi e proteggerli contro una gamma completamente nuova di vettori di attacco. Se li consideri solo come password, ti perderai alcune parti importanti del quadro generale.
5
Conor Mancone

Uno dei motivi principali per cui le password vengono sottoposte a hash prima di memorizzarle è la protezione da un utente malintenzionato che ottiene un accesso di sola lettura al database . In questo modo, se un utente malintenzionato ottiene l'elenco delle credenziali di accesso, non sarà comunque in grado di utilizzarli direttamente perché le password sono sottoposte a hash/salate.

E questo non è solo un problema teorico che stiamo cercando di risolvere qui, questo tipo di attacchi si verificano davvero ( incluso ai principali giocatori in l'industria ) e un hash corretto aiuta a mitigare l'impatto di un attacco.

Se stai permettendo agli utenti di autenticarsi utilizzando un segreto API, il segreto API è diventato effettivamente diventato una password quindi, dal punto di vista della sicurezza, dovrebbero avere lo stesso meccanismi di protezione come le password normali.

Amazon stesso ora non consente il recupero del segreto API . Se lo dimentichi, devi richiederne uno nuovo.

2
Pedro Rodrigues

No, non va bene per alcuni tipi di servizi.

Attuazione

1. Alla connessione dell'utente con la password di accesso, genera una chiave derivata dalla sua password per crittografare i dati per questo utente e tenerli in una sessione sul server.

In questo modo, ogni utente avrà una chiave univoca. Questa chiave derivata non deve essere reversibile, questo è il punto principale. L'uso di hash_mac o altri metodi di hashing con salt e/o master key lo consentirà.

2. Utilizzare questa chiave per crittografare il segreto API generato utilizzando AES 256 con un iv casuale per ciascun utente.

O

2.bis Utilizzare questa chiave per generare la chiave di crittografia reale all'ultimo momento e crittografare il metodo API usando la stessa procedura di 2. per evitare password fluttuanti nella memoria.

. Memorizza iv nella banca dati insieme all'ID utente e all'ID app in una tabella dedicata

4. Memorizza il segreto API crittografato nel database nella tabella appropriata.

so

Ora quando l'utente si collega al suo pannello di controllo è possibile ricreare la chiave, recuperare iv, decifrare il segreto API per questo utente e visualizzarlo in chiaro. È anche possibile visualizzare la chiave e chiedere entrambi quando si effettua una chiamata API in modo da poter verificare il segreto dell'app.

Se si desidera evitare di visualizzare la chiave e non è necessario richiederla sulla chiamata API, è possibile anche per l'autenticazione utilizzare lo stesso metodo utilizzato per l'accesso. Ciò significa che è possibile creare un'altra tabella per archiviare una chiave/salt casuale per ogni app client e memorizzare una versione hash_mac del segreto API. Pertanto, per autenticare la richiesta API sono necessari solo l'ID API e il segreto API. ma è più lavoro.

Nota

Questo è praticamente lo stesso della risposta @Polynomial.

In questo modo è molto difficile per qualcuno hackerare server e database per rubare le credenziali degli utenti ed effettuare chiamate API per loro conto. Ora puoi valutare che se una richiesta è stata accettata da un client API è il client giusto o è la sua perdita.

Se l'utente perde la password, rigenerare un nuovo segreto API e chiave dalla sua nuova password.

0
Nicolas Manzini