Perché un token anti-contraffazione ha bisogno di così tanti bit?

14

Nel link Google consiglia di utilizzare un numero casuale protetto da crittografia a 130 bit come anti-contraffazione token.

Perché abbiamo bisogno di così tanti bit? Se un attaccante decide di montare un attacco a forza bruta, non sarebbe in grado di individuarli e bloccarli dopo alcuni tentativi? Con un minimo di 30 bit, hai 1 milione di token possibili per 1000 utenti simultanei. Indovinare il token usando la forza bruta sembra estremamente improbabile.

Il mio punto è che 30-40 bit di dati sembrano molto difficili da rompere usando la forza bruta. Quindi, perché Google consiglia 130 bit? Non è solo eccessivo?

UPDATE : Ok, dì che non puoi impedire un attacco di forza bruta ...

  • In base al link Facebook riceve 500.000 visitatori unici al minuto.
  • Supponendo che ogni utente effettui una richiesta al secondo, hai una richiesta per 2 microsecondi.
  • Pertanto, possiamo tranquillamente supporre che (a partire da oggi) l'attaccante più potente sarà in grado di inviare al massimo una richiesta per 2 microsecondi.
  • Successivamente, supponiamo di far scadere i token dopo 5 minuti. Ciò significa che un utente malintenzionato può avviare richieste 1.5 * 10 8 prima che il token scada.
  • Successivamente, supponiamo di volere che l'autore dell'attacco abbia meno dell'1% di possibilità di indovinare il token. Pertanto abbiamo bisogno di un pool di token 1.5 * 10 10 per token attivo.
  • Quindi se hai 500.000 utenti simultanei (Facebook) hai bisogno di token 7,5 * 10 15 (un pool per utente).
  • Ciò significa che hai bisogno di 53 bit di dati, che ancora non si avvicinano ai 130 bit richiesti da Google.
posta Gili 03.06.2014 - 06:52
fonte

5 risposte

0

Quando inizi a visualizzare la probabilità di successo di un utente malintenzionato in termini di tempo anziché percentuale, le raccomandazioni di Google diventano molto più ragionevoli.

Prendi la formula trovata al link e scoprirai rapidamente che se vuoi mantenere un attaccante a bada per oltre un anno, avrai bisogno di oltre 100 bit di entropia. 130 bit sono ancora pazzeschi ma iniziano a sembrare un po 'più ragionevoli.

Grazie per avermi indicato nella giusta direzione.

    
risposta data 05.06.2014 - 01:41
fonte
18

La tua domanda presuppone che non si debba fare sul campo:

wouldn't you be able to detect and lock them out after a few attempts

Sì, in un buon ambiente di lavoro dovrebbe esserci un sistema come questo in grado di superare i limiti di velocità di vario tipo. Questa è una buona cosa da fare, ma non dovrebbe mai la tua prima o unica linea di difesa . Se il tuo modello di sicurezza si basa su un livello aggiuntivo come questo per la sua sicurezza teorica, stai introducendo un inutile punto di errore e un possibile vettore di attacco.

Mantenendo la matematica teorica che deve essere fatta fuori dalla tua portata, riduci il rischio posto da cose che potrebbero essere (o eventualmente finire) fuori dal tuo controllo come un'implementazione difettosa del limitatore di velocità o un lavoro di attacco interno.

    
risposta data 03.06.2014 - 08:04
fonte
8

Alcuni altri fattori che contribuiscono alla necessità di così tanta entropia e perché potrebbero suggerire 30 caratteri:

In primo luogo, si tratta di proteggere l'azione di accesso lato applicazione, che creerà quindi la propria sessione autenticata indipendente da quella di Google. L'importante è che sia l'applicazione a memorizzare il token e decidere quando smettere di accettarlo. Se è conservato in una sessione o in una tabella di database, potresti continuare ad accettare quel token indefinitamente e Google non può garantire che le applicazioni non lo facciano, quindi è più facile per loro raccomandare più entropia.

In secondo luogo, propongono l'uso di rand () in PHP in quell'esempio . Ad essere onesti, questo mi sorprende, perché quella funzione non produce numeri casuali crittograficamente sicuri. Infatti secondo i documenti potrebbe solo produrre numeri compresi tra 0 e 32767 su alcuni sistemi. Questo mi suggerisce che 30 caratteri non sono assolutamente necessari per garantire la sicurezza, ma è semplicemente una buona idea.

In terzo luogo penso che "30 caratteri" sia principalmente pertinente al contesto del loro esempio, in cui stanno usando rand () pompato in md5 (). Dato che md5 () produce valori esadecimali, ci sono solo 16 possibili valori per carattere. Inoltre, i digest md5 hanno una lunghezza di 32 caratteri, ma se inizi a troncarlo, sarà molto più facile trovare una collisione.

In breve:

  1. È più facile suggerire un'alta entropia invece di modi complicati per gli sviluppatori di applicazioni per garantire che i valori siano scaduti in modo sicuro e affidabile.
  2. Se le persone prendono il loro codice di esempio (ad esempio md5 (rand ())) e iniziano a troncare il valore a 32 bit, allora un utente malintenzionato può solo trovare tutti i prefissi n caratteri distinti degli hash md5 dei valori da 0 a 32767 , dove n è ciò a cui tronchi. Questo probabilmente produrrà un insieme di valori che potrebbero essere forzati brutalmente entro un tempo ragionevole.
risposta data 03.06.2014 - 10:11
fonte
6

Guardando il codice di esempio su quella pagina:

  • Il codice PHP usa rand() , che su alcuni sistemi è al massimo 15 bit e potrebbe essere ancora meno perché rand() non è necessariamente un buon RNG.
  • Il codice Python utilizza 32 caratteri da un alfabeto di 36 (lettere maiuscole e cifre), che funziona a ca. 165 bit supponendo che random.choice sia perfetto. Che potrebbe non essere, ma stiamo ancora guardando molto più di 15 bit.
  • L'uso di 130 bit nel codice Java rientra tra i due. Non vedo alcuna motivazione ovvia per questo: il numero viene emesso in base 32, quindi per seguire il consiglio "circa 30 caratteri" mi aspetterei 150 bit anziché 130. Potrebbe essere un errore di battitura!
  • Ciò che è costante tra i diversi esempi presentati è che la stringa è lunga "circa 30 caratteri" come consigliato (26 per Java, 32 per gli altri). Questo costante consiglio non ti dice molto sulla sicurezza, ma solo sulla comodità di archiviarlo, trasmetterlo e riceverlo.

Dubito che esista una risposta definitiva a questa domanda, oltre a scoprire come l'autore dello snippet Java in particolare ha scelto il numero 130. Se questa quantità di entropia fosse veramente importante per Il consiglio di sicurezza di Google, quindi anche gli esempi Python e PHP lo userebbero. Cosa che non fanno.

Il principio generale al lavoro è che è economico generare, archiviare e trasmettere queste quantità di dati. In quanto tale, non vi è alcun vantaggio, e alcuni rischi, di utilizzare solo quanto realmente necessario. Il risultato è di consigliare "overkill", anche se il codice PHP non è sufficiente.

Chiedete perché non 1024 bit - beh, codificati in base 64 che richiederebbero 172 caratteri, e forse potreste argomentare che inizia ad avvicinarsi al peso di una pagina web, sebbene sarebbe un tratto. Non sono a conoscenza di alcun motivo per cui non puoi usare token CSRF così grandi, non vale la pena consigliare alle persone di usarli. Scegliere tra 130 e 1024 è una questione (basata sull'esperienza) della differenza tra un comodo overkill e l'ingordigia. Scegliere tra 130 e 64 potrebbe essere più un caso di differenza tra il comfort eccessivo e la sensazione fastidiosa che forse sei in un ordine di grandezza o due di non essere sicuro per forza bruta, dopotutto.

Quindi, quando si fornisce un parere generale su questo tipo di scelta, è abbastanza ragionevole analizzare la situazione peggiore, raddoppiare la risposta (o più) e quindi verificare che il risultato sia entro limiti ragionevoli di risorse. Se è così, basta usarlo. In quanto tale, non aspettatevi che ci sia qualcosa di molto speciale sui numeri 30 o 130. Forse sarebbe stato istruttivo per Google mostrare il suo funzionamento.

    
risposta data 03.06.2014 - 11:45
fonte
1

Il punto è di rendere un attacco a forza bruta non fattibile,

Sì, potresti rendere il token appena abbastanza lungo da corrispondere a una probabilità scelta arbitrariamente in base a determinati presupposti. Ma perché lo faresti? Perché giocare con la sicurezza dei tuoi utenti e della tua applicazione? Non è come un mucchio di bit pseudo-casuali era un enorme fattore di costo.

Qualcosa come 128 bit è una scelta molto comune quando le persone semplicemente non vogliono preoccuparsi di attacchi di forza bruta (o di collisioni accidentali). Puoi trovare questo "numero magico" in molte applicazioni diverse come le chiavi simmetriche, i sali hash, gli UUID ecc.

    
risposta data 04.06.2014 - 05:07
fonte

Leggi altre domande sui tag