Il mio algoritmo di hashing della password personalizzata è insicuro?

16

Per tutti i miei progetti web di hobby, ho codificato un sistema di accesso condiviso da questi progetti. Non ci sono dati critici in questi progetti, gli unici dati critici potrebbero essere le password riutilizzate. Così provo ad hash password in modo molto sicuro.

L'algoritmo di hashing della password corrente non è niente che definirei davvero sicuro. E come ho visto che PHP ora offre hashing build con password_hash , ho pensato di cambiare.

La mia domanda è: quali sono i vantaggi di cambiare per me? In termini di, quale protezione extra ottengo, quale buco (i) devo riparare, ecc.? E c'è qualcos'altro che devo fare per non renderlo estremamente insicuro?

Mi piacerebbe usare le risposte come esperienza di apprendimento per me stesso così posso insegnarlo ad altri che sono nella mia posizione.

Il mio attuale algoritmo (pseudo-codice):

Salt = "some-salt" 
Repeat 1000000 times
    Password = Sha512(Salt + username + Salt + Password) 

So che il mio sito è vulnerabile agli attacchi temporali e le funzioni integrate di PHP lo risolverebbero.

Cos'altro è ovviamente insicuro?

    
posta Kostronor 12.09.2014 - 09:56
fonte

6 risposte

33

Per gli utenti iniziali hai eseguito il rollover del tuo algoritmo di hashing della password. Esistono attualmente tre algoritmi di hashing della password considerati sicuri:

  • PBKDF2
  • scrypt
  • bcrypt

Stai iterando e stai aggiungendo un po 'di sale. Sembra anche che tu aggiunga il nome utente all'interno dell'algoritmo, il che non aggiunge alcun beneficio dato che stai già utilizzando un salt.

Quello che non posso dedurre dal tuo codice e che è molto importante è la lunghezza del tuo sale e il modo in cui lo generi. Un sale non dovrebbe mai essere hardcoded, ma sicuro generato casualmente quando si esegue l'hashing della password. Il sale dovrebbe essere unico all'interno del database e preferibilmente globalmente unico al fine di evitare l'identificazione di password simili in database diversi (quindi un nome utente non è considerato un buon sale).

Anche il modo in cui funziona PBKDF2 (che si appoggia più vicino all'implementazione) è utilizzando un HMAC in cui il sale generato casualmente è la chiave utilizzata per calcolare il digest del messaggio, piuttosto che accodare tutto insieme. La password_hash di PHP sta utilizzando l'algoritmo di bcrypt.

Quindi riassumi ciò che ottieni usando un algoritmo standard invece del tuo:

  • Generai sali casuali
  • Utilizzerai un algoritmo di hashing della password standardizzato e sicuro
risposta data 12.09.2014 - 11:01
fonte
18

Supponendo che some-salt sia in effetti mai ripetuto, questo è un metodo accettabile di hashing della password. Combina i tre elementi essenziali: nessun recupero dell'hash dalle password (grazie all'uso di SHA-512), lentezza intrinseca (a causa dell'elevato numero di iterazioni SHA-512) e un sale unico.

Il sale deve essere unico a livello globale: non deve essere utilizzato per hash altre password, per hash la stessa password in caso di modifica della password o nel database delle password di qualcun altro. Violare l'unicità non è assolutamente fondamentale, ma più accade, più facilmente lo fai per un aggressore. All'estremo della gamma, il "sale" è costante, non è un sale e il metodo di hashing della password è terribile. Se si tratta del nome utente o dell'ID del record, è ancora negativo perché più database condivideranno un piccolo insieme di sali.

Tuttavia, dovresti usare un metodo di hashing standard. Potrebbe esserci una vulnerabilità nel tuo metodo che ci è sfuggita perché si basava su alcuni dettagli sottili. Potresti aver commesso un errore nell'implementazione; per questo motivo è preferibile un'implementazione ben supportata con aggiornamenti di sicurezza. Un punto debole può essere scoperto nell'algoritmo; di nuovo, è meglio usare un'implementazione ben supportata il cui implementatore si tiene al corrente delle notizie di crittografia e cambierà l'algoritmo se necessario.

Una cosa che devi fare attenzione è aumentare il numero di iterazioni con il passare del tempo ei computer diventano più veloci. Un buon

Leggi Come password di hash sicure? (sì , tutto). Bcrypt è in qualche modo superiore a PBKDF2, perché è più resistente agli attacchi basati su GPU; PBKDF2 segue gli stessi principi del tuo hash personalizzato. L'uso di PBKDF2 non è una vulnerabilità principale a questo punto, ma vorrei comunque passare a bcrypt o scrypt.

    
risposta data 12.09.2014 - 15:10
fonte
16

Il tuo algoritmo è migliore per miglia rispetto a molti "homebrew". Il motivo per cui passerei a uno standardizzato è il vantaggio di tutti i controlli che questi standard hanno ricevuto che la tua costruzione non ha.

Non c'è sicuramente nessun errore nella tua costruzione che permetta una rottura banale? In caso contrario, sei sicuro che il tuo algoritmo non sia vulnerabile a un attacco brute-force accelerato utilizzando GPU massicciamente parallele? Potrebbe esserci una forma ottimizzata di attacco da tavolo arcobaleno sul tuo particolare algoritmo?

Probabilmente la risposta è no, no e no, ma più persone hanno guardato al PBKDF2 che al tuo algoritmo, quindi c'è meno probabilità di essere qualcosa di sgradevole che nessuno ha visto finora. Questo è un argomento euristico, ma non dimenticare, anche se il tuo algoritmo è buono (e certamente non mi sembra stupido), ci sono centinaia di altre persone là fuori che hanno implementato la propria crittografia che si è rivelata orribilmente rotta . Ecco perché diciamo, di regola, non eseguire il rollover.

È la stessa ragione per cui non permettiamo a nessuno di installare e modificare le connessioni elettriche ad alta tensione: avere la qualifica di un elettricista non ti protegge magicamente dalla scarica elettrica, ma significa che hai sperato di avere abbastanza esperienza nell'area non fare nulla di troppo stupido come afferrare un filo casuale e vedere se è vivo o no.

    
risposta data 12.09.2014 - 15:29
fonte
8

Uno svantaggio di includere il nome utente come parte di sale è che non puoi rinominare un utente (ad esempio, amministrativamente) senza generare un nuovo hash della password (il che significa che dovresti scegliere una nuova password e dirlo all'utente, oppure chiedere all'utente la loro password corrente).

    
risposta data 12.09.2014 - 18:47
fonte
3

Prima di tutto, dal punto di vista della sicurezza delle password hai un algoritmo piuttosto buono.

Il tuo sale non è tecnicamente un sale, poiché è lo stesso per ogni utente, ma quando lo si combina con il nome utente è un pezzo unico di informazioni, quindi si ha la sicurezza completa di un sale. Se la stringa "un po 'saltata" è crittograficamente strong (almeno 64 bit di entropia), funziona anche come pepe .

Da un punto di vista della convenienza, in genere si vorrebbe evitare di includere il nome utente nell'algoritmo hash della password, in quanto ciò rende complicato cambiare il nome utente e sarà necessaria la password in testo semplice per l'operazione. Un sale dedicato è più facile da gestire.

Un milione di iterazioni di hashing sembra un po 'esagerato, potrebbe facilmente diventare il collo di bottiglia di un sito Web occupato, ridimensionarlo a un livello in cui è possibile eseguire almeno 1000 hash di password al secondo.

Assicurati anche di avere un meccanismo per limitare i tentativi di accesso, se un utente malintenzionato può semplicemente masterizzare 1000 tentativi di accesso al secondo per rubare rapidamente molti account utente con password deboli, oppure può usare l'hashing della password come diniego di arma di servizio.

Non penso che ci sia una prassi largamente condivisa per la limitazione dell'accesso, tranne per il fatto che nessuna limitazione è la soluzione peggiore possibile.

    
risposta data 13.09.2014 - 13:03
fonte
2

Riesco a vedere alcuni problemi con il tuo approccio.

  • Sembra che tu stia usando un valore salato costante. È più sicuro generare un nuovo valore per ogni password.
  • Includere il nome utente nel sale può essere problematico. Come sottolineato da Andrew, significa che non è possibile rinominare un utente. In parte attenua il problema con un sale costante. Ma non attenua completamente il problema, perché il nome utente non cambia ogni volta che cambia la password.
  • Si include solo la password nella prima iterazione. Esiste il rischio teorico che l'entropia della password scompaia lentamente mentre si itera.
  • Il conteggio delle iterazioni elevate potrebbe renderti vulnerabile agli attacchi DoS.

Il conteggio delle iterazioni è un'arma a doppio taglio. Un elevato numero di iterazioni rende il server vulnerabile agli attacchi DoS. Il conteggio delle iterazioni ridotte rende il database delle password vulnerabile agli attacchi di forza bruta offline. L'unico modo per proteggersi da entrambi è quello di scaricare parte del calcolo sul client. Ma questo richiede un codice sul client. In un servizio web tale codice potrebbe essere fornito da javascript, ma javascript non è veloce quanto il codice nativo, quindi l'autore dell'attacco avrebbe un vantaggio rispetto all'uso legittimo.

    
risposta data 13.09.2014 - 10:48
fonte

Leggi altre domande sui tag