it-swarm-eu.dev

N. di iterazioni consigliate quando si utilizza PKBDF2-SHA256?

Sono curioso di sapere se qualcuno ha qualche consiglio o punto di riferimento quando si tratta di determinare quante iterazioni sono "abbastanza buone" quando si utilizza PBKDF2 (in particolare con SHA-256). Certamente, "abbastanza buono" è soggettivo e difficile da definire, varia in base all'applicazione e al profilo di rischio, e ciò che oggi è "abbastanza buono" probabilmente non sarà "abbastanza buono" domani ...

Ma la domanda rimane: cosa pensa attualmente l'industria 'abbastanza buono'? Quali punti di riferimento sono disponibili per il confronto?

Alcuni riferimenti che ho trovato:

  • Settembre 2000 - Consigliati oltre 1000 colpi (fonte: RFC 2898)
  • Febbraio 2005 - AES in Kerberos 5 "default" a 4096 round di SHA-1. (fonte: RFC 3962)
  • Settembre 2010 - ElcomSoft afferma che iOS 3.x utilizza 2.000 iterazioni, iOS 4.x utilizza 10.000 iterazioni, mostra BlackBerry utilizza 1 (l'algoritmo hash esatto non è dichiarato) (fonte: ElcomSoft )
  • Maggio 2011 - LastPass utilizza 100.000 iterazioni di SHA-256 (fonte: LastPass )
  • Giu 2015 - StableBit utilizza 200.000 iterazioni di SHA-512 (fonte: StableBit CloudDrive Nuts & Bolts )
  • Agosto 2015 - CloudBerry utilizza 1.000 iterazioni di SHA-1 (fonte: CloudBerry Lab Security Consideration (pdf) )

Apprezzerei eventuali riferimenti o feedback aggiuntivi su come hai determinato quante iterazioni fossero "abbastanza buone" per la tua applicazione.

Come sfondo aggiuntivo, sto prendendo in considerazione PBKDF2-SHA256 come il metodo utilizzato per hash delle password degli utenti per l'archiviazione per un sito Web attento alla sicurezza. Il mio sale PBKDF2 pianificato è: un sale casuale per utente (memorizzato in chiaro con ogni record utente) XOR con un sale globale. L'obiettivo è aumentare il costo della forzatura brutale delle password ed evitare di rivelare coppie di utenti con password identiche.

Riferimenti:

  • RFC 2898: PKCS # 5: specifica di crittografia basata su password v2.0
  • RFC 3962: crittografia Advanced Encryption Standard (AES) per Kerberos 5
  • PBKDF2: Funzione di derivazione chiave basata su password v2
195
Tails

È necessario utilizzare il numero massimo di round tollerabile, dal punto di vista delle prestazioni, nella propria applicazione. Il numero di round è un fattore di rallentamento, che si utilizza sulla base del fatto che in normali condizioni di utilizzo, tale rallentamento ha un impatto trascurabile per te (l'utente non lo vedrà, il costo aggiuntivo della CPU non implica l'acquisto di un server più grande, e presto). Ciò dipende fortemente dal contesto operativo: quali macchine sono coinvolte, quante autenticazioni utente al secondo ... quindi non esiste una risposta unica per tutti.

L'immagine ampia va così:

  • Il tempo per verificare una singola password è v sul sistema. È possibile regolare questa volta selezionando il numero di round in PBKDF2.
  • Un potenziale attaccante può raccogliere f volte più potenza della CPU di te (ad esempio, hai un singolo server e l'attaccante ha 100 PC di grandi dimensioni, ciascuno due volte più veloce del tuo server: questo porta a f = 200 ).
  • L'utente medio ha una password di entropia n bit (ciò significa che il tentativo di indovinare una password utente, con un dizionario di "password plausibili", richiederà in media 2n-1 tenta).
  • L'attaccante troverà il tuo sistema degno di essere attaccato se la password media può essere decifrata in un tempo inferiore a p (questa è la "pazienza" dell'attaccante).

Il tuo obiettivo è far sì che il costo medio per infrangere una singola password superi la pazienza dell'attaccante, in modo che non ci provi nemmeno e continui a concentrarsi su un altro obiettivo più semplice. Con le notazioni dettagliate sopra, questo significa che vuoi:

v · 2n-1 > f · p

p è al di fuori del tuo controllo; può essere stimato rispetto al valore dei dati e dei sistemi protetti dalle password degli utenti. Diciamo che p è 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 cercherà di aumentare f acquistando macchine più grandi. Un punto aggravante è che il crack della password è un'attività imbarazzantemente parallela , quindi l'attaccante otterrà un grande impulso usando un GPU che supporta la programmazione generale ; quindi una tipica f sarà comunque compresa nell'ordine di alcune centinaia.

n si riferisce alla qualità delle password, che puoi in qualche modo influenzare attraverso una rigorosa politica di selezione delle password, ma realisticamente avrai difficoltà a ottenere un valore di n oltre, diciamo, 32 bit. Se provi a imporre password più forti, gli utenti inizieranno a combatterti attivamente, con soluzioni alternative come riutilizzare password da altrove, scrivere password su foglietti adesivi 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 , è necessario v essere almeno 241 millisecondi (nota: inizialmente ho scritto "8 millisecondi" qui, 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 così, perché, ammettiamolo, ottenere 32 bit di entropia dalla password dell'utente media è un po 'ottimista; d'altra parte, non molti attacchi dedicheranno dozzine di PC per un mese intero al compito di decifrare una singola password, quindi forse una "pazienza dell'aggressore" di un giorno è più realistica, portando a un costo di verifica della password di 8 millisecondi.

Quindi è necessario fare alcuni parametri di riferimento. Inoltre, quanto sopra funziona fino a quando l'implementazione PBKDF2/SHA-256 è veloce. Ad esempio, se si utilizza un'implementazione completamente basata su C #/Java, si otterrà il tipico fattore di rallentamento da 2 a 3 (rispetto a C o Assembly) per attività ad alta intensità di CPU; nelle notazioni precedenti, ciò equivale a moltiplicare f per 2 o 3. Come base di confronto, una CPU Core2 a 2,4 GHz può eseguire circa 2,3 milioni di calcoli elementari SHA-256 al secondo (con un singolo core), quindi ciò implicherebbe, su quella CPU, circa 20000 round per raggiungere l'obiettivo "8 millisecondi".


(*) Assicurati che rendere la verifica della password più costosa renda il tuo server più vulnerabile a attacchi Denial of Service . È necessario applicare alcune contromisure di base, come inserire temporaneamente nella lista nera gli indirizzi IP dei client che inviano troppe richieste al secondo. Devi farlo comunque, per contrastare gli attacchi del dizionario online .

230
Thomas Pornin

Correre openssl speed dalla riga di comando per avere un'idea di quanto siano veloci le funzioni di digest dei messaggi. Posso calcolare circa 1,6 milioni di hash sha256 al secondo o circa 145 miliardi supposizioni al giorno sul mio quad core 2.2ghz Sandy Bridge. Se qualcuno ha una password che si trova nel dizionario inglese e ha usato un round di sha256, ci vorrebbe più tempo per caricare l'elenco di parole dal disco piuttosto che iterare sull'elenco per interrompere l'hash. Se facessi PKBDF2-SHA256 con qualche centinaio di colpi, ci vorrebbero alcuni minuti per rompersi. L'applicazione di una politica di password complessa aiuta, molto.

La vera risposta: quanto tempo devi perdere?

32
rook

La risposta di Thomas fornisce un modello e dati di base utili. Ma l'obiettivo che pone non ha senso per me. Un utente malintenzionato tipico non conoscerà il conteggio delle iterazioni fino a quando non avrà effettivamente violato il sito e acquisito il database di hash. Fatto ciò, non andranno avanti solo perché si utilizza un conteggio di iterazioni elevato. Proveranno a decifrare il maggior numero possibile e probabilmente pubblicizzeranno gli hash, così altri continueranno a provare a decifrarli per anni a venire con hardware sempre più potente. Quindi "p" e "f" continueranno entrambi ad aumentare a lungo dopo l'hacking.

Inoltre, le password degli utenti reali non sono ben modellate da una misura di complessità come 32 bit di entropia. L'articolo Reusable Security: New Paper on Password Security Metrics è utile in questo senso e documenta ciò che sappiamo da tempo: molti utenti scelgono password facili da indovinare, e c'è una lunga coda. Questo significa anche che gli attaccanti ne troveranno sempre alcuni se si impegnano abbastanza.

Direi che un obiettivo più probabile sarebbe quello di proteggere una percentuale quanto più ampia possibile dei tuoi utenti dall'infrangere le loro password. Per esempio. la tabella 4.2.1 del PDF mostra che se sei riuscito a limitare l'attaccante durante una campagna di attacco da una media di 1 milione di tentativi per hash a 500.000 tentativi , potresti proteggere le password del 5% dei tuoi utenti (ipotizzando un mix con più password di 7 caratteri rispetto a 8+ password di caratteri, riducendo così la percentuale di cracking dal 35% al ​​30%). Naturalmente la forma esatta della curva e la sua posizione varieranno notevolmente.

Quindi sceglierei il conteggio massimo di iterazioni per il quale è possibile eseguire il budget, a condizione che non ritardi gli utenti reali a effettuare accessi normali. E dovresti aumentare il valore man mano che la tua capacità di calcolo cresce nel corso degli anni.

17
nealmcb

Una macchina moderna equipaggiata con 8 GPU di generazione attuale calcolerà nell'ordine di 9 miliardi di hash SHA-256 al secondo, o circa 777 trilioni di hash al giorno, e quelle GPU possono eseguire attacchi a dizionario basati su regole.

0
ModernMachine

Prendi questo come un commento molto lungo. Ero curioso di sapere come funzionano le cose sul mio laptop personale (Thinkpad T460p, Intel i7-6700HQ ). So che per decifrare le password salate ci sono dispositivi speciali, ma se hai un servizio web probabilmente non hai hardware speciale per quello.

Risultati della valutazione

L'impostazione predefinita di werkzeug.security.generate_password_hash attualmente (01-06-2019) è pbkdf2:sha256:150000.

Come puoi vedere, il tempo di esecuzione aumenta linearmente con il numero di round/iterazioni. Ciò significa che l'impostazione predefinita richiede circa 281 ms in media sulla mia macchina.

enter image description here

enter image description here

sha512,     1 iteration : min:   67.1μs, mean:    72.2μs, max:   310.9μs
sha512, 15000 iteration: min: 38462.8μs, mean: 40291.2μs, max: 44842.4μs
sha256, 15000 iteration: min: 27167.6μs, mean: 28118.0μs, max: 30826.0μs
sha512,  1000 iteration: min:  2636.7μs, mean:  2694.3μs, max:  3579.0μs
sha256,  1000 iteration: min:  1870.7μs, mean:  1888.8μs, max:  2477.0μs
md5,    15000 iteration: min: 21126.2μs, mean: 21864.8μs, max: 23799.3μs
sha512,     1 iteration : min:   23.4μs, mean:    26.9μs, max:    40.6μs
sha512,  1000 iteration: min:  2586.7μs, mean:  2761.1μs, max:  3120.6μs
sha256,  1000 iteration: min:  1823.3μs, mean:  1834.6μs, max:  2008.5μs
sha512, 15000 iteration: min: 38507.9μs, mean: 40210.8μs, max: 47430.3μs
sha256, 15000 iteration: min: 27257.1μs, mean: 28454.0μs, max: 31213.5μs
md5,    15000 iteration: min: 21219.9μs, mean: 21842.4μs, max: 24305.0μs

Codice

0
Martin Thoma