Dovresti usare il numero massimo di round che è tollerabile, in termini di prestazioni, nella tua applicazione. Il numero di round è un fattore di rallentamento, che viene utilizzato sulla base del fatto che in condizioni di utilizzo normali, tale rallentamento ha un impatto trascurabile per l'utente (l'utente non lo vedrà, il costo aggiuntivo della CPU non implica l'acquisto di un server più grande, e presto). Questo dipende strongmente dal contesto operativo: quali macchine sono coinvolte, quante autenticazioni degli utenti al secondo ... quindi non esiste una risposta valida per tutti.
L'immagine ampia va così:
- Il tempo per verificare una singola password è v sul tuo sistema. Puoi regolare questa volta selezionando il numero di round in PBKDF2.
- Un potenziale attaccante può raccogliere f più potenza della CPU di te (ad esempio, hai un singolo server, e l'attaccante ha 100 computer di grandi dimensioni, ognuno due volte più veloce del tuo server: questo porta a < em> f = 200 ).
- L'utente medio ha una password di entropia n bit (questo significa che cercare di indovinare una password utente, con un dizionario di "password plausibili", richiederà in media 2 n-1 try).
- L'attaccante troverà il tuo sistema che merita di essere attaccato se la password media può essere spezzata in meno di p (che è la "pazienza" dell'attaccante).
Il tuo obiettivo è quello di fare in modo che il costo medio per rompere una singola password superi la pazienza dell'attaccante, in modo che non ci provi nemmeno e si concentri su un altro obiettivo più facile. Con le notazioni sopra descritte, questo significa che vuoi:
v · 2 n-1 > f · p
p è fuori dal tuo controllo; può essere stimato in relazione al valore dei dati e dei sistemi protetti dalle password dell'utente. Diciamo che p è di un mese (se impiega più di un mese, l'attaccante non si preoccuperà di provare). Puoi rendere f più piccolo acquistando un server più grande; d'altra parte, l'attaccante proverà a rendere f più grande acquistando macchine più grandi. Un punto aggravante è che il cracking della password è un imbarazzante parallelo compito, quindi l'autore dell'attacco otterrà una grande spinta utilizzando un GPU che supporta la programmazione generale ; quindi un f tipico continuerà a variare nell'ordine di alcune centinaia.
n si riferisce alla qualità delle password, che puoi in qualche modo influenzare attraverso una severa politica di selezione delle password, ma realisticamente ti sarà difficile ottenere un valore di n oltre, per esempio, 32 bit. Se cerchi di imporre password più efficaci, gli utenti inizieranno a combattere attivamente con soluzioni alternative come riutilizzare le password da altrove, scrivere password su note adesive e così via.
Quindi il parametro rimanente è v . Con f = 200 (un attaccante con una dozzina di buone GPU), una pazienza di un mese e n = 32 , hai bisogno di v per essere almeno 241 millisecondi (nota: inizialmente ho scritto "8 millisecondi", che è sbagliato - questa è la cifra per una pazienza di un giorno invece di un mese). Quindi dovresti impostare il numero di round in PBKDF2 in modo tale che il calcolo su una singola password richieda almeno tanto tempo sul tuo server. Sarai comunque in grado di verificare quattro password al secondo con un singolo core, quindi l'impatto della CPU è probabilmente trascurabile (*). In realtà, è più sicuro usare più round di questo, perché, ammettiamolo, ottenere 32 bit di entropia dalla password utente media è un po 'ottimistico; d'altra parte, non molti attacchi dedicheranno dozzine di PC per un intero mese al compito di crackare una singola password, quindi forse una "pazienza dell'attaccante" di un giorno è più realistica, portando a un costo di verifica della password di 8 millisecondi.
Quindi devi fare alcuni benchmark. Inoltre, quanto sopra funziona finché l'implementazione di PBKDF2 / SHA-256 è veloce. Ad esempio, se si utilizza un'implementazione completamente in C # / Java, si otterrà il tipico fattore di rallentamento 2-3 (rispetto a C o assembly) per le attività a uso intensivo della CPU; nelle notazioni di cui sopra, questo equivale a moltiplicare f di 2 o 3. Come base di confronto, una CPU Core2 a 2,4 GHz può eseguire circa 2,3 milioni di calcoli elementari di SHA-256 al secondo (con un singolo core), quindi questo implicherebbe, su quella CPU, circa 20000 round per raggiungere l'obiettivo "8 millisecondi".
(*) Fare attenzione che rendere la verifica della password più costosa rende anche il server più vulnerabile a Denial-of-Service attacchi . È necessario applicare alcune contromisure di base, come la lista nera degli indirizzi IP dei client che inviano troppe richieste al secondo. Devi comunque farlo, per contrastare gli attacchi del dizionario online .