PBKDF2 e Bcrypt non supportano l'aumento del costo, a partire dall'output con un dato numero di iterazioni, senza conoscenza della password. Non c'è una ragione intrinseca per quello; un processo di hashing della password potrebbe consentire tale allungamento offline pur rimanendo "buono". Ma questi algoritmi capita di non permetterlo.
Ciò che può essere fatto è il seguente: un normale output bcrypt o PBKDF2 include il s salt, il conteggio iterativo i e l'output hash v . Nelle implementazioni di bcrypt, i tre valori sono spesso codificati in caratteri stampabili (con una codifica tipo Base64); vedi ad esempio questa risposta . Supponendo che tu abbia s e v , puoi memorizzare quanto segue:
- the salt s ;
- un conteggio iterativo i ;
- un conteggio iterativo aggiuntivo j ;
- il valore h (h (h (... h (h (v)) ...))) che è il risultato di hashing v ripetutamente, con una funzione di hash sicura h , fatta j volte.
Per la verifica della password, devi ricalcolare bcrypt / PBKDF2 dalla password specificata (usando s e i ), e poi eseguire l'hash del valore risultante j volte, per vedere se corrisponde al valore memorizzato.
Questo è per lo più sicuro, se usi una strong funzione di hash per h , come SHA-256. Si può dimostrare che l'hashing ripetuto riduce lo spazio dei valori possibili, ma dovrebbe raggiungere un "ciclo" interno di dimensione all'incirca sqrt (N) se i valori di output dell'hash sono in uno spazio di dimensioni N ; inoltre, se quel ciclo è abbastanza piccolo da essere esplorato esaurientemente, può essere calcolata una collisione sulla funzione hash h (vedi questa pagina per un bel diagramma). Quindi, se h è resistente alle collisioni (come SHA-256), lo schema sopra è sicuro.
Il punto importante è che puoi aumentare j in seguito, in modo offline. Tuttavia , nota che questo tipo di stretching si basa sul costo di elaborazione coinvolto nel fare molti calcoli di funzioni hash extra. Sfortunatamente, le solite funzioni di hash come SHA-256 si adattano molto bene a ciò che la GPU può fare; quindi, il vantaggio ottenuto in quel modo sull'attaccante potrebbe non essere così grande come inizialmente desiderato. In altre parole, l'uso dello stretching descritto sopra annulla qualsiasi vantaggio di bcrypt su PBKDF2 (vedi questa risposta per una discussione su questo argomento). Potresti applicarlo come misura temporanea, fino a quando il suddetto utente non ritorna, in modo che il passaggio bcrypt possa essere eseguito di nuovo con un conteggio di iterazioni più elevato ( i ).
Inoltre , lo schema che descrivo sopra è crypto fatto in casa, e questo è male. Posso farla franca perché sono assolutamente fantastico, ma questo non può essere promosso su base generale.