Domanda:
Numero consigliato di iterazioni quando si utilizza PKBDF2-SHA256?
Tails
2011-05-20 03:32:55 UTC
view on stackexchange narkive permalink

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 usa PBKDF2 (in particolare con SHA-256). Certamente, "abbastanza buono" è soggettivo e difficile da definire, varia a seconda dell'applicazione Profilo di rischio di &, e ciò che è "abbastanza buono" oggi probabilmente non è "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 individuato:

  • Settembre 2000 - 1000+ cicli consigliati (fonte: RFC 2898)
  • febbraio 2005 - AES in Kerberos 5 'predefinito' 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)
  • giugno 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 qualsiasi riferimento o feedback aggiuntivo su come hai determinato quante iterazioni erano "abbastanza buone" per la tua applicazione.

Come sfondo aggiuntivo, sto prendendo in considerazione PBKDF2-SHA256 come metodo utilizzato per l'hashing 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'ed con un sale globale. L'obiettivo è aumentare il costo della forzatura bruta delle password ed evitare di rivelare coppie di utenti con password identiche.

Riferimenti:

  • RFC 2898: PKCS # 5: Password- Specifica di crittografia basata v2.0
  • RFC 3962: crittografia AES (Advanced Encryption Standard) per Kerberos 5
  • PBKDF2: funzione di derivazione della chiave basata su password v2
Anche se lo contrassegno come risposta, apprezzerei comunque tutti i riferimenti che documentano quante iterazioni usano altre applicazioni ... Grazie.
Un sale globale non aggiunge alcuna protezione aggiuntiva contro i tavoli arcobaleno. Se stai utilizzando il sale globale per prevenire tentativi di cracking offline, potresti voler [considerare l'utilizzo di un HMAC] (http://security.stackexchange.com/questions/19243/should-password-hashes-be-encrypted-or -hmaced) invece. Inoltre, considera l'utilizzo di bcrypt o scrypt invece di PBKDF2-SHA256, poiché sono progettati con lo scopo esplicito di hashing lentamente le password.
Nota obbligatoria per tutti coloro che vengono qui: al giorno d'oggi dovresti seriamente considerare l'utilizzo di algoritmi di allungamento delle chiavi migliori di PKBDF2 in quanto è altamente parralizzabile. Considera [Argon2] (https://en.wikipedia.org/wiki/Argon2) come l'ultima cosa (vincitore nel 2015), o scrypt o giù di lì.
Cinque risposte:
#1
+239
Thomas Pornin
2011-05-20 17:43:14 UTC
view on stackexchange narkive permalink

Dovresti usare il numero massimo di round tollerabile, dal punto di vista delle prestazioni, nella tua applicazione. Il numero di round è un fattore di rallentamento, che utilizzi sulla base del fatto che in condizioni di utilizzo normali, un 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 in larga misura dal contesto operativo: quali macchine sono coinvolte, quante autenticazioni utente al secondo ... quindi non esiste una risposta valida per tutti.

L'immagine ampia è così:

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

Il tuo obiettivo è fare in modo che il costo medio per violare una singola password superi la pazienza dell'aggressore, in modo che non ci provi nemmeno e continui a concentrarsi su un altro bersaglio più facile. Con le notazioni descritte sopra, questo significa che vuoi:

v · 2 n-1 > f · p

p è al di fuori del tuo controllo; può essere stimato in relazione al valore dei dati e dei sistemi protetti dalle password degli utenti. Diciamo che p è un mese (se ci vuole più di un mese, l'attaccante non si preoccuperà di provare). Puoi rimpicciolire f acquistando un server più grande; d'altra parte, l'attaccante cercherà di ingrandire f acquistando macchine più grandi. Un punto aggravante è che il cracking delle password è un'attività imbarazzantemente parallela, quindi l'aggressore otterrà un grande impulso utilizzando una GPU che supporta la programmazione generale; quindi una tipica f varia ancora nell'ordine di poche centinaia.

n si riferisce alla qualità delle password, che puoi in qualche modo influenzare attraverso una rigida 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ù sicure, gli utenti inizieranno a combatterti 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 , è necessario v per essere almeno 241 millisecondi (nota: inizialmente ho scritto "8 millisecondi" qui, il 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 lo stesso tempo sul tuo server. Sarai comunque in grado di verificare quattro password al secondo con un singolo core, quindi l'impatto sulla CPU è probabilmente trascurabile (*). In realtà, è più sicuro usare più round di così, perché, ammettiamolo, ottenere 32 bit di entropia dalla password utente media è un po 'ottimistico; D'altra parte, non molti attacchi dedicheranno decine di PC per un mese intero al compito di crackare una singola password, quindi forse la "pazienza di un attaccante" di un giorno è più realistica, portando a un costo di verifica della password di 8 millisecondi.

Quindi è necessario fare alcuni benchmark. Inoltre, quanto sopra funziona fintanto che l'implementazione di 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 le attività che richiedono molta 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 SHA-256 elementari al secondo (con un singolo core), quindi questo implicherebbe, su quella CPU, circa 20000 round per raggiungere l'obiettivo "8 millisecondi".


(*) Fai attenzione che rendere più costosa la verifica della password rende anche il tuo server più vulnerabile agli attacchi Denial of Service. È necessario applicare alcune contromisure di base, come l'inserimento temporaneo nella blacklist degli indirizzi IP dei client che inviano troppe richieste al secondo. Devi farlo comunque, per contrastare gli attacchi ai dizionari online .

+1 per l'ottima risposta, se potessi darei un altro +1 per l'imbarazzante collegamento parallelo :-)
Questo è un ottimo modo di pensarci - grazie!
Solo un'idea: si potrebbe fare come ~ 20k round sul PC client e di 1k sul server? Se un attaccante iniziasse a indovinare "password normali", dovrebbe comunque fare 21k round. E se iniziasse con le chiavi, avrebbe solo bisogno di fare 1k round, ma l'entropia dovrebbe essere molto più alta. Mi sto perdendo qualcosa? Mi sembra una buona soluzione.
@cooky451: puoi farlo, ma può essere difficile da configurare. I clienti possono utilizzare un'ampia varietà di hardware, alcuni dei quali molto deboli quando si tratta di computer. Inoltre, in un contesto Web, questo significa Javascript, e non otterrai molte iterazioni da un'implementazione _Javascript_ di PBKDF2 (_ funzionerebbe molto meglio con un'applet Java, ma questa è ancora un'altra lattina di worm).
Non capisco come sei arrivato a 8 ms nel tuo esempio. Se f = 200, p = 30 * 24 * 60 * 60 * 1000 ?, n = 32. Allora v è 241 ms? Ho trasformato 1 mese in millisecondi. Non sono sicuro di cosa sto facendo di sbagliato. Grazie per la risposta
Viene fuori a 241 ms. Infatti, se si inseriscono 8 ms nella formula, si ottengono circa 23 ore di "pazienza dell'aggressore". Che è molto meno di un mese (per una singola password entropica a 32 bit) ... E abbastanza basso dove il valore consigliato di 8 ms dovrebbe essere probabilmente aumentato.
Ecco uno script veloce per il benchmarking di PBKDF2 (nota: il tempo è riportato in secondi): https://gist.github.com/sarciszewski/a3b1cf19caab3f408bf8
Concordo con la tua valutazione, con una precisazione: il numero di iterazioni non dovrebbe essere basato su quanto tempo impiega il * tuo * hardware per eseguire l'operazione.Deve essere basato sulla quantità di tempo in cui l'hardware di un * utente malintenzionato * può eseguire l'operazione.Se hai un hardware debole, non è una buona scusa per scegliere `iterations = 1`.La tua lunga spiegazione prosegue descrivendola in modo ragionevole, ma la tua conclusione iniziale è "per quanto pensi vada bene nel tuo ambiente".Dovrebbe essere "qualunque cosa serva per contrastare un aggressore nel suo ambiente".
Stiamo aggiornando la crittografia nella nostra app esistente.Tuttavia, avere un'iterazione elevata causerà un enorme calo delle prestazioni poiché il nostro sistema a volte deve fare i conti con la crittografia / decrittografia di migliaia di voci.Quindi sembra che dovremo usare un valore di iterazione molto basso, probabilmente non più di 1.000.Quindi la domanda che mi pongo è che dovremmo anche preoccuparci di un valore così basso?Perché non andare semplicemente con "1"?
#2
+33
rook
2011-05-20 04:00:30 UTC
view on stackexchange narkive permalink

Esegui openssl speed sulla riga di comando per avere un'idea di quanto siano veloci le funzioni di message digest. Posso calcolare circa 1,6 milioni di hash sha256 al secondo o circa 145 miliardi di ipotesi al giorno sul mio ponte sabbioso quad core da 2,2 GHz. Se qualcuno ha una password che si trova nel dizionario inglese e ha utilizzato un round di sha256, sarebbe necessario più tempo per caricare l'elenco di parole dal disco che per iterare l'elenco per rompere l'hash. Se facessi PKBDF2-SHA256 con poche centinaia di migliaia di colpi, ci vorrebbero alcuni minuti per interromperlo. L'applicazione di una policy di password efficace aiuta, molto .

La vera risposta: quanto tempo hai a disposizione?

Punti buoni. velocità openssl - bello! Ma con 200.000 giri, a 2 M giri al secondo, sono solo 10 al secondo. Un piccolo dizionario con centomila parole richiederebbe alcune ore. Ma sì, anche con molti round, una cattiva password è cattiva ...
AiliyunzbiCMT risolto.
#3
+17
nealmcb
2011-05-21 00:53:20 UTC
view on stackexchange narkive permalink

La risposta di Thomas fornisce un modello di base e dati utili. Ma l'obiettivo che si pone non ha senso per me. Un tipico aggressore non conoscerà il conteggio delle iterazioni fino a quando non avrà effettivamente hackerato il sito e preso il database degli hash. Fatto ciò, non andranno avanti solo perché usi un conteggio di iterazioni elevato. Cercheranno di crackarne il maggior numero possibile, e molto probabilmente pubblicizzeranno gli hash in modo che altri continueranno a provare a decifrarli per anni a venire con hardware sempre più potente. Quindi "p" e "f" continueranno ad aumentare a lungo dopo l'hack.

Inoltre, le password degli utenti reali non sono ben modellate da una misura di complessità come 32 bit di entropia. L'articolo Sicurezza riutilizzabile: nuovo documento sulle metriche di sicurezza delle password è utile a questo proposito e documenta ciò che sappiamo da tempo: molti utenti scelgono password facili da indovinare e c'è una lunga coda. Ciò significa anche che gli aggressori ne troveranno sempre alcuni se si sforzano abbastanza.

Direi che un obiettivo più probabile sarebbe quello di proteggere la più ampia percentuale possibile dei tuoi utenti dal crackare le loro password. Per esempio. la tabella 4.2.1 del PDF mostra che se sei riuscito a limitare il tuo aggressore durante una campagna di attacco da una media di 1 milione di tentativi per hash fino a 500.000 tentativi, potresti proteggere le password del 5% di i tuoi utenti (ipotizzando un mix con più password di 7 caratteri rispetto a password di 8+ caratteri, riducendo così la percentuale di cracking dal 35% al ​​30%). Ovviamente la forma esatta della curva e la posizione in cui si trovano varieranno ampiamente.

Quindi sceglierei il numero massimo di iterazioni per il quale puoi preventivare, purché non ritardi utenti reali che eseguono accessi normali. E dovresti aumentare il valore man mano che la tua capacità di calcolo cresce nel corso degli anni.

#4
+3
Martin Thoma
2019-06-01 11:57:06 UTC
view on stackexchange narkive permalink

Prendilo come un commento molto lungo. Ero curioso di sapere quanto velocemente funzionino le cose sul mio laptop personale (Thinkpad T460p, Intel i7-6700HQ). So che per decifrare le password salate esistono 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 (2019-06-01) è pbkdf2:sha256:150000.

Come puoi vedete, il tempo di esecuzione cresce linearmente con il numero di round / iterazioni. Ciò significa che il valore predefinito richiede circa 281 ms in media sulla mia macchina.

enter image description here

enter image description here

  sha512, 1 iterazione: min: 67,1μs, media: 72,2μs, max: 310,9μssha512, 15000 iterazione: min: 38462,8μs, media: 40291,2μs, max: 44842,4μssha256, 15000 iterazione: min: 27167,6μs, media: 28118,0μs, max: 30826,0μssha512, 1000 iterazione: min: 2636,7μs, media: 2694,3μs, max: 3579,0μssha256, 1000 iterazione: min: 1870,7μs, media: 1888,8μs, max: 2477,0μsmd5, 15000 iterazione: min: 21126.2μs, media: 21864,8μs, max: 23799,3μssha512, 1 iterazione: min: 23,4μs, media: 26,9μs, max: 40,6μssha512, 1000 iterazione: min: 2586,7μs, media: 2761,1μs, max: 3120,6μssha256, 1000 iterazione: min: 1823,3μs, media: 1834,6μs, max: 2008,5μssha512, 15000 iterazione: min: 38507,9μs, media: 40210,8μs, max: 47430,3μssha256, 15000 iterazione: min: 27257,1μs, media: 28454,0 μs, max: 31213,5μsmd5, 15000 iterazione: min: 21219,9μs, media: 21842,4μs, max: 24305,0μs  

C ode

#5
+1
ModernMachine
2012-06-19 20:48:48 UTC
view on stackexchange narkive permalink

Una macchina moderna dotata di 8 GPU della generazione attuale calcolerà nell'ordine di 9 miliardi di hash SHA-256 al secondo, ovvero circa 777 trilioni di hash al giorno, e quelle GPU possono eseguire attacchi ai dizionari basati su regole.

Come aggiornamento a questo, nell'ottobre 2014, per [https://hashcat.net/oclhashcat/”(https://hashcat.net/oclhashcat/), le velocità sono fino a 12,3 miliardi di hash SHA-256 al secondo (e 4,5 miliardi di hash SHA-512 al secondo) per quella macchina con 8 GPU, utilizzando GPU AMD R9 290X.
Quali sono le statistiche aggiornate ora?
per https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a270c40 SHA-256 ~ 23 miliardi di hash al secondo, SHA-512 ~ 8,6 miliardi di hash al secondo, utilizzando 8x Nvidia GTX 1080


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...