Va bene se il segreto dell'API è memorizzato in testo normale o decodificato?

32

Non sono stati considerati% nomi utente API keys e API secrets ha considerato le password? Perché i server API come Amazon Web Services ti consentono di visualizzare il tuo segreto API in formato testo? Mi fa pensare che lo memorizzino in testo normale o almeno in un formato compatibile con la decrittografia.

Non è forse meglio se i segreti dell'API venissero considerati come password da digitare per creare l'hash nel database invece di essere consegnati in testo normale? Se per qualche motivo il loro database segreto API è stato compromesso, aprirà facilmente i gate di inondazione per molte applicazioni che utilizzano la loro API. Tuttavia, se è stato sottoposto a hash in modo non decrittografabile, tutto non è facilmente perso.

    
posta IMB 12.08.2012 - 21:11
fonte

8 risposte

17

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 archiviata in chiaro sul server. Se il server ha memorizzato solo un hash della chiave API, non è stato possibile verificare l'autenticità dei messaggi dal client o autenticare i messaggi inviati al client.

    
risposta data 13.08.2012 - 08:28
fonte
13

L'hashing non è memoria; distrugge irreversibilmente i dati. Possiamo usare hashing password come "password storage" perché quando abbiamo effettivamente bisogno della password, abbiamo un comodo operatore umano per scriverlo. Infatti, quando abbiamo cancellato la password, non memorizziamo la password, ma solo un token sufficiente per verificare la password digitata.

Una chiave API deve essere archiviata in modo che possa essere riutilizzata in modo incustodito . Il server deve davvero archiviare , invece di ricordare solo un fantasma di esso, perché ha bisogno della chiave originale per accedere all'API.

    
risposta data 13.08.2012 - 13:27
fonte
8

Anche se sarebbe più sicuro hash 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. Ciò rende un po 'difficile proteggerli con un hash.

Il mio suggerimento per uno scenario sicuro sarebbe il seguente:

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

Quando l'utente effettua l'accesso, la webapp conosce la sua password e la utilizza per calcolare k , che viene quindi utilizzata per decrittografare la chiave API e mostrarla a loro.

Quando l'utente desidera utilizzare l'API, deve inviare k e la chiave API in chiaro, su SSL. La webapp può quindi decodificare il valore della chiave API memorizzata utilizzando k e confrontarlo con la chiave API fornita. Se corrispondono, è valido. Ciò consente l'utilizzo delle chiavi API senza che l'app debba memorizzare la password dell'utente.

Se un utente malintenzionato viola il database, deve craccare la password dell'utente per calcolare k .

    
risposta data 13.08.2012 - 00:42
fonte
6

Qui sembra esserci un po 'di confusione e altri luoghi , quindi aggiungo 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 la maggior parte delle risposte di questa pagina stanno discutendo è una chiave segreta che viene utilizzata per firmare e verificare i messaggi utilizzando un algoritmo come HMAC. In questo caso, sia il client che l'API richiedono il 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, questo non può funzionare. Dopo aver inizialmente condiviso la chiave con il client (su un canale crittografato), la chiave non deve essere più trasmessa tra il client e il 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 solo conservare sufficienti informazioni 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 effettivamente come una password, quindi devono essere prese le stesse precauzioni.

Disclaimer: non sono un ricercatore di sicurezza e dovresti assolutamente fare ulteriori ricerche su questo e su qualsiasi argomento prima di seguire ciecamente i consigli su questo StackExchange.

tl; dr Il takeaway più importante è che diverse API possono utilizzare il segreto in modi diversi. È importante capire in che modo la tua API utilizza il segreto del client per valutare le migliori pratiche per la sua archiviazione.

    
risposta data 12.07.2017 - 19:06
fonte
4

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

C'è un'altra importante differenza tra una chiave API e una password. Le API Key sono uniche per il tuo sito. La parte che rende la sicurezza delle password così importante è la condivisione delle password. Se qualcuno ottiene una sospensione della password che un utente ha salvato sul tuo sito, non è solo il tuo sito a essere compromesso: è ogni altro sito che l'utente ha utilizzato per tale password (e email / nome utente). Molte persone riutilizzano le password su siti critici: banche, social media, e-mail, ecc. Ciò significa che una buona protezione della password non riguarda tanto la protezione dell'accesso al sito quanto la protezione degli utenti su altri siti. Non possiamo costringere gli utenti a fare meglio la sicurezza, quindi dobbiamo assumere il peggio e adottare ulteriori misure per proteggere la loro privacy.

Una chiave API è uno scenario completamente diverso perché è univoco per il tuo sito. Di conseguenza, se viene rubato, l'attaccante ottiene l'accesso al tuo sito, ma non guadagna nulla che possa fare leva sulla banca / email / etc di quella persona. Ciò significa che il livello di rischio per le chiavi API è in realtà inferiore a quello per le password. Non si trovano esattamente nello stesso parco: le chiavi API sono più simili agli identificatori di sessione che alle password.

Capire che questi sono più affini 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 API Keys per cose come le credenziali OAuth e non le credenziali di crittografia (come discusso da @NickSloan nella sua risposta).

Le maggiori minacce alle password sono attacchi di phishing e database compromessi, motivo per cui li archiviamo con hash nei nostri database. Le maggiori minacce alle chiavi API sono le stesse delle chiavi di sessione: punti deboli nelle applicazioni front-end quali 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 fa guadagnare nulla quando la persona che ha più probabilità di rubarla ne ha bisogno in testo normale.

Proteggi invece un identificatore di sessione (o token OAuth o chiave API specifica del client) principalmente tenendo traccia del cliente. Se un identificativo di sessione viene rubato tramite XSS o altri mezzi dal client, un tipico risultato è che quell'identificatore venga usato dall'attaccante su un nuovo dispositivo. Ciò significa che all'improvviso vedrai una vecchia chiave in arrivo con un nuovo agente utente. Tale modifica è facile da rilevare e correggere: invalida immediatamente tutte le chiavi API. Soprattutto nel caso delle richieste OAuth, questo è molto semplice per l'utente: si collegano nuovamente e ne ottengono immediatamente uno nuovo, mentre qualcuno che ha appena rubato la chiave (e non ha la password) è tornato alla lavagna .

Questa è una misura di difesa abbastanza comune che un hacker più intelligente proverà anche a registrare l'agente utente associato alla chiave rubata e lo userà in tutte le future richieste, ma puoi comunque vedere facilmente qualcosa di strano mentre lo stesso utente ha richieste provenienti da più indirizzi IP. Come qualsiasi altra cosa al mondo, questo può essere un gioco di tipo "gatto e topo", ma ci sono alcuni importanti contenuti da portare via:

  1. Una chiave API / Token OAuth / ID sessione è in realtà solo un modo per ricordare un utente su un particolare dispositivo, in modo che non debbano inserire la password su ogni pagina. Di conseguenza, in caso di dubbio, puoi semplicemente uccidere tutte le chiavi autorizzate e forzare l'utente a eseguire di nuovo l'accesso.
  2. In tutti e tre i casi, dal momento che la perdita di Key / Token / ID porta a un account compromesso, è importante avere una certa sicurezza attiva su queste cose e rilevare / rispondere se succede qualcosa di strano. Se hai mai ricevuto avvisi da parte di facebook / google / etc su qualcuno che sta tentando di accedere al tuo account dal Messico, è perché un responsabile della sicurezza da qualche parte sta facendo il proprio lavoro.
  3. I vettori di attacco principali per Chiavi / Token / Id sono diversi da quelli delle password. Potresti ancora volerli hash nel tuo database (ancora una volta, non stiamo parlando di credenziali di crittografia che devono essere in chiaro), ma non puoi semplicemente inserirli nel tuo database e chiamarti sicuro. È necessario assicurarsi e proteggerli contro una nuova gamma di vettori di attacco. Se li consideri solo come password, ti perderai alcune parti importanti del quadro generale.
risposta data 12.07.2017 - 19:45
fonte
2

Uno dei principali motivi per cui le password vengono sottoposte a hashing prima di memorizzarle, è quello di proteggere contro 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 utilizzarle direttamente perché le password sono state sottoposte a hash / salate.

E questo non è solo un problema teorico che stiamo cercando di risolvere qui, questi tipi di attacchi accadono davvero ( compresi i principali attori del settore ), e l'hashing appropriato aiuta a mitigare l'impatto di un attacco.

Se ti lascio che gli utenti eseguano l'autenticazione utilizzando un'API segreta, allora il segreto dell'API diventa effettivamente una password pertanto, dal punto di vista della sicurezza, dovrebbero avere gli stessi meccanismi di protezione delle normali password.

Amazon stesso ora non consente di recuperare il segreto dell'API . Se lo dimentichi, devi chiederne uno nuovo.

    
risposta data 28.02.2017 - 11:38
fonte
0

No, non va bene per alcuni tipi di servizi.

Implementazione

1. In seguito alla connessione dell'utente con la password di accesso, generare una chiave derivata dalla propria password per crittografare i dati per questo utente e mantenerlo 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'utilizzo di hash_mac o di un altro metodo di hashing con sale e / o chiave master lo consentirà.

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

O

2.bis Usa questa chiave per generare la vera chiave di crittografia all'ultimo momento e crittografare il metodo API usando lo stesso metodo di 2. per evitare di memorizzare password mobili.

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

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

Utilizzo

Ora quando l'utente si connette al suo pannello di controllo è possibile ricreare la chiave, recuperare iv, decifrare il segreto dell'API per questo utente e visualizzarlo in testo non crittografato. Puoi anche visualizzare la chiave e chiedere entrambi quando effettui la chiamata API in modo da poter verificare il Segreto dell'app.

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

Nota

Questo è praticamente lo stesso di @Polynomial answer.

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

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

    
risposta data 29.11.2015 - 12:10
fonte
-2

Bene, in questo back-end puoi anche eseguire il provisioning del server e leggere comunque tutti i dati. Devi assicurarti che nessuno possa accedere al tuo back-end, altrimenti leggerà tutti i tuoi dati contemporaneamente inclusi i backup.

    
risposta data 12.08.2012 - 21:26
fonte