2009-10-07 16 views
20

Mi è stato chiesto di implementare alcune modifiche/aggiornamenti a un sito intranet; renderlo "a prova di futuro" come lo chiamano.Come aggiornare uno schema di archiviazione password (modificare l'algoritmo di hashing)

Abbiamo rilevato che le password vengono sottoposte a hash utilizzando l'algoritmo MD5. (il sistema è in circolazione dal 2001, quindi è stato adeguato in tempo).
Ora vorremmo aggiornare l'algoritmo di hashing a uno più forte (BCrypt-hash o SHA-256).

Ovviamente non conosciamo il testo in chiaro-password e la creazione di una nuova password per l'utenza è non un'opzione*).

Quindi, la mia domanda è:

Qual è il modo accettato di cambiare hashing algoritmo senza avere accesso alle password in chiaro?
La soluzione migliore sarebbe una soluzione completamente "dietro le quinte".

*) abbiamo provato; ho cercato di convincerli, abbiamo usato l'argomento "età della password", ho provato a corromperli con il caffè, ho provato a corromperli con la torta, ecc. ecc. Ma è non un'opzione.

Aggiornamento
speravo in una sorta di soluzione automagic per risolvere il problema, ma a quanto pare non ci sono altre opzioni che solo 'attendere per l'utente di accedere, quindi convertire'.

Bene, almeno ora ora non ci sono altre soluzioni disponibili.

risposta

24

Innanzitutto, aggiungere un campo al DB per identificare se la password sta utilizzando MD5 o il nuovo algoritmo.

Per tutte le password ancora utilizzando MD5:

- Nel processo di login, dove si verifica password immessa di un utente: memorizzare temporaneamente la password presentato dell'utente in memoria (nessun problema di sicurezza qui, in quanto è già in memoria da qualche parte) e fare il solito hash MD5 & confrontare con l'hash memorizzato;

- Se è stata fornita la password corretta (corrisponde all'hash esistente), eseguire la password temporaneamente archiviata tramite il nuovo algoritmo, memorizzare tale valore, aggiornare il nuovo campo per identificare che questa password è stata aggiornata al nuovo algoritmo.

(Naturalmente si sarebbe solo utilizzare il nuovo algoritmo per tutti i nuovi utenti/nuove password.)

3

Aggiungi password Modificare il campo data/ora nel database.

Tutto password impostata prima del giorno X, controllare utilizzando MD5

tutte le password impostate dopo giorno X, controllare utilizzando bcrypt o qualsiasi altra cosa.

+0

E cambiare la password dell'utente quando accede da MD5 a BCrypt. – Dennis

3

È possibile memorizzare, o nel campo hash stesso (ad esempio "MD5: d41d8cd98f00b204e9800998ecf8427e") o in un'altra colonna, quale algoritmo è stato utilizzato per creare tale hash. Quindi dovresti modificare la procedura di accesso per utilizzare l'algoritmo corretto quando controlli la password. Ovviamente, qualsiasi nuova password verrà sottoposta a hash utilizzando il nuovo algoritmo. Si spera che le password alla fine scadano e, nel tempo, tutti gli hash MD5 verranno eliminati gradualmente.

+1

È anche possibile che la procedura di accesso "aggiorni" la password al nuovo algoritmo di hashing, presupponendo che si abbia accesso alla password in chiaro in quel momento. – Craig

+1

D'oh! Certo che puoi, e dovresti. –

3

Dal momento che non si conosce la password in chiaro, forse si dovrebbe creare un campo che indica la versione encription (come PasswordVersion bit default 0)

utente La prossima volta prova a connettersi, controllare la password hash utilizzando la versione algoritmo corrente, proprio come tu fai oggi Se corrisponde, cancellalo di nuovo e aggiorna il campo PasswordVersion.

Speriamo che tu non abbia bisogno di una colonna PasswordVersion più grande di bit. =)

+0

"Spero che tu non abbia bisogno di una colonna di PasswordVersion più grande del bit" mi ha fatto sorridere (+1) – Jacco

+0

Davvero, non fare il presupposto che hai capito bene questa volta. Usa 'byte' per la tua PasswordVersion. –

+1

Solo 8 tentativi per farlo bene? Rendilo un 'int' e avrai spazio sufficiente per impostare il tuo errore personale ... =) –

3

si consiglia di modificare il database password per memorizzare 3 articoli:

  1. Un algoritmo di identificazione.
  2. Una stringa salt casuale scelta dal server quando calcola e memorizza l'hash della password.
  3. L'hash della concatenazione di sale + password utilizzando l'algoritmo specificato.

Naturalmente queste potrebbero semplicemente essere memorizzati insieme in un campo di testo con un delimitatore:

"SHA256: questo-è-sale: questo-è-hash-valore"

Ora convertire voci che esistenti per un valore di sale vuote e il vecchio algoritmo di

"MD5 :: questo-è-il-old-md5-hash-senza-sale"

Ora si dispone di informazioni sufficienti per verificare tutte le voci di password esistenti, ma è anche possibile verificare le nuove voci (poiché si conosce la funzione di hash utilizzata). È possibile convertire le vecchie voci per il nuovo algoritmo la prossima volta che gli utenti esistenti login in quanto si avrà la loro password disponibili durante questo processo:

  1. Se il database indica che stanno utilizzando il vecchio algoritmo senza sale, prima verifica la password alla vecchia maniera controllando che l'hash MD5 della password corrisponda. In caso contrario, rifiuta l'accesso.
  2. Se la password è stata verificata, chiedere al server di selezionare una stringa salt random, calcolare l'hash SHA256 di salt + password e sostituire la voce della tabella password con una nuova specificando il nuovo algoritmo, salt e hash.
  3. Quando l'utente si collega nuovamente, vedrete che stanno usando il nuovo algoritmo, quindi calcola l'hash della password salt + e verifica che corrisponda all'hash memorizzato.

Alla fine, dopo che questo sistema è stato in esecuzione per un tempo adeguato, è possibile disabilitare gli account che non sono stati convertiti (se lo si desidera).

L'aggiunta di una stringa salt casuale unica per ogni voce rende questo schema molto più resistente agli attacchi di dizionario che utilizzano le tabelle arcobaleno.

+0

il vecchio schema MD5 ha già utilizzato l'hashing appropriato. – Jacco

+0

Non sono sicuro di aver compreso il tuo commento, a meno che con "hashing corretto" si intenda che hai già aggiunto un valore salt prima di eseguire l'hashing della password con MD5. Se è così, lo schema per l'aggiornamento funziona ancora, è sufficiente prendere in considerazione il sale durante la verifica con MD5. –

5

Non sono completamente sicuro di questa opzione, dal momento che non sono un esperto di crittografia. Per favore correggimi se sbaglio ad un certo punto qui!

Penso che Dave P. abbia chiaramente l'opzione migliore.

... ma. Esiste una soluzione automagic: hash gli stessi hash più vecchi. Cioè, prendi gli hash correnti, e cancellali di nuovo con un algoritmo più forte. Si noti che, per quanto comprendo, non si ottiene alcuna sicurezza aggiuntiva dalla lunghezza dell'hash qui, solo la complessità crittografica aggiunta del nuovo algoritmo.

Il problema è, naturalmente, che il controllo di una password dovrebbe passare attraverso entrambi gli hasc. E tu dovresti fare lo stesso anche per la nuova password. Che è, beh, praticamente stupido. A meno che tu non voglia usare uno schema simile come Dave P. ha spiegato alla fine di tornare alle password single-hash con il nuovo algoritmo di hash ... in tal caso, perché preoccuparsi di questo? (Certo, potresti usarlo in un vistoso "Miglioramento della sicurezza per tutte le password, applicato immediatamente!" - via a una presentazione per i semi aziendali, con una faccia relativamente seria ...)

Ancora, è un'opzione che può essere applicato immediatamente a tutte le password correnti, senza alcuna fase graduale di migrazione.

Ma ragazzo, oh ragazzo, qualcuno farà una bella risata guardando quel codice più tardi! :)

+0

Sembra la cosa che stavo cercando. Ma non sono sicuro delle implicazioni dell '"hashing hash", credo di aver letto da qualche parte che i risultati potrebbero essere non ottimali in determinate condizioni. Ma non lo so. – Jacco

+1

Questa è una cattiva idea, perché se c'è una collisione nel primo hash, allora c'è una collisione nell'algoritmo combinato. E ci sono collisioni note in MD5. –

+2

@Richard, perché una collisione hash importa in questo contesto? –

Problemi correlati