Qual è l'approccio migliore per generare una nuova chiave API?


92

Quindi con molti servizi diversi in giro ora, API di Google, API di Twitter, API di Facebook, ecc.

Ogni servizio ha una chiave API, come:

AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q

Tutte le chiavi variano in lunghezza e i caratteri che contengono, mi chiedo quale sia l'approccio migliore per generare una chiave API?

Non sto chiedendo una lingua specifica, solo l'approccio generale alla creazione di chiavi, dovrebbe essere una crittografia dei dettagli dell'app degli utenti, o un hash, o un hash di una stringa casuale, ecc. Dovremmo preoccuparci dell'algoritmo hash (MSD, SHA1, bcrypt) ecc.?

Modifica: ho parlato con alcuni amici (e-mail / twitter) e mi hanno consigliato di utilizzare solo un GUID con i trattini rimossi.

Questo però mi sembra un po 'complicato, sperando di avere qualche idea in più.


Ho risposto in modo più dettagliato qui .. generando chiavi e usandolo come hmac auth
Anshu Kumar

Risposte:


59

Utilizza un generatore di numeri casuali progettato per la crittografia. Quindi la base 64 codifica il numero.

Questo è un esempio in C #:

var key = new byte[32];
using (var generator = RandomNumberGenerator.Create())
    generator.GetBytes(key);
string apiKey = Convert.ToBase64String(key);

2
Non è molto sicuro, un utente malintenzionato che ottiene l'accesso al database potrebbe ottenere la chiave. Sarebbe meglio generare la chiave come un hash di qualcosa di unico per l'utente (come un sale), combinato con un segreto del server.
James Wierzba

14
L'archiviazione di una chiave API generata in modo casuale ha le stesse caratteristiche di sicurezza dell'archiviazione di una password con hash. Nella maggior parte dei casi, va bene. Come suggerisci, è possibile considerare il numero generato casualmente come un salt e hashing con un segreto del server; tuttavia, così facendo, si incorre in un overhead hash su ogni convalida. Non è inoltre possibile invalidare il segreto del server senza invalidare tutte le chiavi API.
Edward Brey

Bella soluzione, ma probabilmente è necessaria la parola chiave var prima di apiKey :) var apiKey = Convert.ToBase64String (key);
Dawid Ohia

@ JohnM2 Giusto. L'avevo lasciato aperto, poiché apiKeypoteva essere dichiarato altrove. Ho aggiunto il tipo per chiarezza.
Edward Brey

4
@JamesWierzba se l'attacco è già nel tuo database, allora il fatto che abbia un accesso non protetto alla tua API è probabilmente l'ultima delle tue preoccupazioni ...
Jon Story

30

Le chiavi API devono avere le proprietà che:

  • identificare in modo univoco un utente API autorizzato - la parte "chiave" della "chiave API"
  • autenticare l'utente - non può essere indovinato / falsificato
  • può essere revocato se un utente si comporta male, in genere inserisce un database che può avere un record eliminato.

In genere avrai migliaia o milioni di chiavi API, non miliardi, quindi non è necessario:

  • Archivia in modo affidabile le informazioni sull'utente API perché possono essere archiviate nel tuo database.

Pertanto, un modo per generare una chiave API è prendere due informazioni:

  1. un numero di serie a garanzia dell'unicità
  2. abbastanza bit casuali per riempire la chiave

e firmarli utilizzando un segreto privato.

Il contatore garantisce l'identificazione univoca dell'utente e la firma impedisce la falsificazione. La revocabilità richiede il controllo che la chiave sia ancora valida nel database prima di eseguire qualsiasi operazione che richieda l'autorizzazione della chiave API.

Un buon generatore di GUID è un'approssimazione abbastanza buona di un contatore incrementato se è necessario generare chiavi da più data center o se non si dispone di un buon modo distribuito per assegnare numeri di serie.


o un hash di una stringa casuale

L'hashing non impedisce la contraffazione. La firma è ciò che garantisce che la chiave provenga da te.


3
La fase di firma del tuo algoritmo è necessaria se la chiave API presentata da un client viene confrontata con un database di chiavi API già registrate sul server che fornisce l'API? Sembra che la firma sarebbe ridondante qui se il server è quello che fornisce le chiavi.
sappenin

3
@sappenin, Sì. Se si memorizza una chiave non indovinabile sul server, non è necessario impedire la falsificazione. Spesso le richieste API vengono gestite da una qualsiasi di una farm di macchine: il server è uno dei tanti server. Il controllo della firma può essere eseguito su qualsiasi macchina senza un viaggio di andata e ritorno a un database che può evitare le condizioni di gara in alcuni casi.
Mike Samuel,

1
@MikeSamuel se la chiave API è firmata e non fai un viaggio di andata e ritorno al database, cosa succede quando la chiave viene revocata ma ancora utilizzata per accedere all'API?
Abhyudit Jain

@AbhyuditJain, In qualsiasi sistema distribuito, è necessario un ordine coerente dei messaggi (le revoche avvengono prima degli usi successivi delle credenziali revocate) o altri modi per limitare l'ambiguità. Alcuni sistemi non eseguono il round trip su ogni richiesta: se un nodo memorizza nella cache il fatto che una chiave è rimasta nel database per 10 minuti, rimangono solo 10 minuti. finestra in cui un utente malintenzionato può abusare di una credenziale revocata. Tuttavia, può verificarsi una possibile confusione: l'utente revoca una credenziale, quindi verifica che sia revocata ed è sorpreso perché le sessioni non adesive fanno sì che le due richieste vadano a nodi diversi.
Mike Samuel

5

Uso gli UUID, formattati in minuscolo senza trattini.

La generazione è facile poiché la maggior parte delle lingue è incorporata.

Le chiavi API possono essere compromesse, nel qual caso un utente potrebbe voler annullare la propria chiave API e generarne una nuova, quindi il metodo di generazione della chiave deve essere in grado di soddisfare questo requisito.


15
Non dare per scontato che gli UUID siano difficili da indovinare; non dovrebbero essere usati come capacità di sicurezza (spec UUID RFC4122 sezione 6 ). Una chiave API richiede un numero casuale sicuro, ma gli UUID non sono indovinabili in modo sicuro .
Edward Brey

3
@EdwardBrey e UUID uuid = UUID.randomUUID();in Java? Stai dicendo che casuale non è abbastanza buono?
Micro

8
@MicroR Un UUID casuale è sicuro solo se il generatore di numeri casuali utilizzato per realizzarlo è crittograficamente sicuro e 128 bit sono sufficienti. Sebbene l'UUID RFC non richieda un generatore di numeri casuali sicuro, una data implementazione può utilizzarne uno gratuitamente. Nel caso di randomUUID , la documentazione API specifica che utilizza un "generatore di numeri pseudo casuali crittograficamente forte". Quindi quella particolare implementazione è sicura per una chiave API a 128 bit.
Edward Brey

4

Se desideri una chiave API con solo caratteri alfanumerici, puoi utilizzare una variante di base64-random , utilizzando invece solo una codifica base 62. L'encoder base 62 si basa su questo .

public static string CreateApiKey()
{
    var bytes = new byte[256 / 8];
    using (var random = RandomNumberGenerator.Create())
        random.GetBytes(bytes);
    return ToBase62String(bytes);
}

static string ToBase62String(byte[] toConvert)
{
    const string alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    BigInteger dividend = new BigInteger(toConvert);
    var builder = new StringBuilder();
    while (dividend != 0) {
        dividend = BigInteger.DivRem(dividend, alphabet.Length, out BigInteger remainder);
        builder.Insert(0, alphabet[Math.Abs(((int)remainder))]);
    }
    return builder.ToString();
}

1

Una chiave API dovrebbe essere un valore casuale. Abbastanza casuale da non poter essere previsto. Non deve contenere alcun dettaglio dell'utente o dell'account a cui appartiene. Usare gli UUID è una buona idea, se sei certo che gli ID creati siano casuali.

Le versioni precedenti di Windows producevano GUID prevedibili, ad esempio, ma questa è una vecchia storia.


4
Windows 2000 è passato ai GUID utilizzando numeri casuali . Tuttavia, non vi è alcuna garanzia che i numeri casuali non possano essere previsti. Ad esempio, se un utente malintenzionato crea diverse chiavi API per se stesso, potrebbe essere possibile determinare un numero casuale futuro utilizzato per generare la chiave API di un altro utente. In generale, non considerare gli UUID come non indovinabili in modo sicuro .
Edward Brey
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.