"token sicuri" generatori di pre-generazione

2

Nella nostra app Web utilizziamo i token monouso. Ad esempio, quando qualcuno crea uno dei tre "account", reimposta la password o qualsiasi altro numero di elementi che richiedono token casuali monouso, noi:

  1. Genera 32 byte casuali dal CSPRNG del SO
    1. Base-64 URL lo codifica
    2. Archivia l'hash nel nostro database (Scrittura con N = 2 ^ 15, r = 8, P = 1)
    3. Assegna all'utente il token monouso (in genere sotto forma di URL)

Tutto funziona bene. Tuttavia, attraverso il profiling abbiamo notato che alcune delle nostre chiamate API possono richiedere un paio di secondi perché devono verificare e creare token. Alcune chiamate API useranno Scrypt tre o più volte.

Anche se non è terribile, vorremmo velocizzare le chiamate API se possibile.

Mi è venuta l'idea di pre-generare alcuni token casuali, ma mi piacerebbe un secondo parere prima di andare avanti e iniziare da questo.

Ci sono due modi in cui penso che potremmo fare questo. Per prima cosa, dovremmo semplicemente creare (triple, hash, sale) le triple e memorizzarle nella memoria. Il lato negativo di questo è che avremmo i token non criptati seduti lì e che un attaccante potrebbe prenderli e usarli. Tuttavia, ciò richiederebbe l'accesso all'istanza AWS specifica e i token monouso sarebbero l'ultima delle nostre preoccupazioni in quella situazione.

Il secondo sarebbe utilizzare un vault di qualche tipo, quindi le tuple sono ancora in memoria, ma sono criptate. Questo sembra più sicuro, ma richiede ancora la password al vault di stare seduto da qualche parte e quindi l'attaccante avrebbe comunque accesso ad esso se avesse accesso all'istanza di AWS.

Pensieri? Sono un po 'diffidente nei confronti di questa idea, ma mi piacerebbe davvero ridurre alcune chiamate API da tre secondi a meno di un secondo.

    
posta Eric Lagergren 11.03.2016 - 22:49
fonte

3 risposte

1

Riepilogo: non è necessario utilizzare scrypt su dati veramente casuali come il tuo. Basta usare un hash sicuro come SHA256 e starai bene.

Spiegazione: Hash come SHA256 sono, per quanto ne sappiamo, irreversibili. L'unico modo per passare da un hash al testo originale è usare una combinazione di precomputazione e forzatura bruta. Risulta che il precalcolo ha molto successo nella memorizzazione delle password perché le persone scelgono password deboli e prevedibili. Ecco perché è necessario creare tutta la scienza degli hash delle password.

Tuttavia, contiene 256 bit di entropia. Non è possibile generare una tabella arcobaleno (non abbiamo spazio per memorizzarla su questo pianeta) o forza bruta ( il sole esploderà prima di arrivare a metà) un semplice hash SHA256 su uno spazio di input così ampio.

Quindi usa il veloce SHA256 sui tuoi dati casuali e ti assicuriamo che non è incrinabile.

    
risposta data 12.03.2016 - 01:10
fonte
0

Invece di eseguire lo scrypt su un token casuale, per questo genere di situazioni genererei un hmac. Ecco un esempio di codice di token di annullamento dell'iscrizione e-mail open source di reddit :

def generate_notification_email_unsubscribe_token(user_id36, user_email=None,
                                                  user_password_hash=None):
    """Generate a token used for one-click unsubscribe links for notification
    emails.
    user_id36: A base36-encoded user id.
    user_email: The user's email.  Looked up if not provided.
    user_password_hash: The hash of the user's password.  Looked up if not
                        provided.
    """
    import hashlib
    import hmac

    if (not user_email) or (not user_password_hash):
        user = Account._byID36(user_id36, data=True)
        if not user_email:
            user_email = user.email
        if not user_password_hash:
            user_password_hash = user.password

    return hmac.new(
        g.secrets['email_notifications'],
        user_id36 + user_email + user_password_hash,

Se hai bisogno di assicurarti che venga usato una sola volta, puoi anche inserire quel valore nel tuo database ed eliminarlo una volta usato, come fai attualmente.

    
risposta data 12.03.2016 - 00:31
fonte
0

Dici che ti preoccupi che gli attaccanti possano accedere ai token se li pre-generi. Sebbene questo tecnicamente dia loro una finestra più grande, sarebbe molto più difficile per un utente malintenzionato monitorare il tuo token sicuro generato comunque.

Il motivo per cui le password di hash sono così future violazioni negli anni a venire non rivelano le password. In questo caso, solo 1 minuto nelle violazioni passate rappresenta un problema. Se qualcuno ti ha violato 1 minuto fa, probabilmente possono violare anche te.

Il mio suggerimento è questo:

  • Avere un programma che genera, ad esempio, 600 token sicuri. Isolare la memoria di questo programma da altri programmi e processi nel miglior modo possibile. Ad esempio, rendilo un utente diverso rispetto alle altre cose.)
  • Qualsiasi processo può richiedere un token dal programma. Quando viene richiesto un token, viene rimosso dal pool.
  • A seconda di come sei paranoico, chiedi al programma di scartare i 10 token più vecchi al secondo e di generarne 10 nuovi. In questo modo, qualsiasi token può durare solo un minuto.

La risposta di Neil è corretta (se per qualche ragione Sha256 agisce lentamente per te, puoi usare sopra).

    
risposta data 13.03.2016 - 03:43
fonte

Leggi altre domande sui tag