La soluzione più semplice è probabilmente aggiungere una colonna "tipo hash password" al database. Impostalo inizialmente su "vecchio"; quando un utente effettua il login, re-hash la password usando il nuovo algoritmo e imposta il tipo di database su "nuovo".
Una variante di questo metodo è per memorizzare il tipo di hash come parte della stringa di hash. Funziona altrettanto bene, purché sia possibile distinguere in modo univoco i diversi formati hash e ha il vantaggio che è possibile includere anche altri parametri necessari (come lo salt e il fattore di lavoro per key stretching) nella stessa stringa senza avere aggiungere campi aggiuntivi per ciascuno al tuo database.
Per esempio, questo è l'approccio utilizzato dalla modern Unix crypt(3) implementations (e le corrispondenti funzioni in vari linguaggi di alto livello come PHP): un classico DES-based (e orribilmente debole) hash della password sarebbe simile abJnggxhB/yWI
, mentre un (leggermente) più moderno hash potrebbe apparire come $1$z75qouSC$nNVPAk1FTd0yVd62S3sjR1
, dove 1
ha specificato il metodo di hashing, z75qouSC
è il sale e nNVPAk1FTd0yVd62S3sjR1
l'hash effettivo e il delimitatore $
viene scelto perché non può apparire in un hash DES vecchio stile.
Il metodo si suggeriscono, dove i nuovi hash sono calcolate come:
hash = new_hash(old_hash(password))
può essere utile in alcuni casi, in quanto consente a tutti i record esistenti da aggiornare, senza dover attendere gli utenti di accedere. Tuttavia, è sicuro solo se la vecchia funzione di hash conserva una quantità sufficiente di entropia nelle password. Ad esempio, anche una funzione di hash crittografica abbastanza vecchia e debole, come unsalted MD5, ad esempio, sarebbe abbastanza buona, poiché il suo output dipende dall'intero input e ha fino a 128 bit di entropia, che è più di quasi qualsiasi password avrà (e più che abbastanza per resistere ad un attacco di forza bruta, comunque). D'altra parte, provare ad applicare questa costruzione usando la vecchia funzione crypt basata su DES (3) come il vecchio hash sarebbe disastroso, poiché la vecchia crypt (3) ignorerebbe tutti tranne i primi 8 caratteri di ciascuna password (come bene come i pezzi più significativi anche di quei personaggi).
fonte
2013-01-18 16:53:00
A mio parere, il doppio hashing è un'idea orribile. Uno dei motivi per cui hai cancellato una password, è che se il tuo hash è trapelato, non possono ancora autenticarsi come utente. Se si esegue new_hash ($ raw_password) per primo, un utente può accedere inserendo il vecchio hash trapelato nel campo della password. Sconfiggere lo scopo di passare a un algoritmo di hash sicuro. – Lemon
@Lemon - Ovviamente il vecchio hash della password nel database verrà sostituito con il doppio hash, ma hai ragione, questa non è la soluzione ottimale. Ho modificato la risposta per mostrare le migliori pratiche, utilizza ancora l'hashing doppio, ma segna il vecchio hash. – martinstoeckli