Prova di lavoro come hash della password una buona idea?

2

I nostri utenti accedono con nome utente / password e hanno un cookie che consente loro di rimanere loggati. I nostri utenti sono tenuti a eseguire versioni aggiornate di JS.

Supponendo che qualcuno stacchi il nostro database a un certo punto,

È una buona idea ridurre l'entropia delle nostre password memorizzate facendo in modo che gli utenti eseguano una prova ragionevole dell'attività di lavoro al momento del login e invialo come password e aumenti la difficoltà nel corso degli anni?

Che cosa fa:

  • proteggere gli utenti dall'avere le loro password deboli incrinate e associate alle loro identità online

Cosa non funziona:

  • fornire un codice di sessione
  • fornire protezione DDoS
  • fornire qualsiasi altra sicurezza del server

registrazione / login clientide:

h = password
d = "0000f"
do: 
  h = hash (h + username + salt)
while (h > d)

send("login", username, h)

login serveride:

d = "0000f"
listen("login", username, h)
if h > d:
  user = database.get(username)
  if user.pass == h:
    send("accepted", true)
    session.user = user

login client parte 2:

listen("accepted", accepted)
if accepted:
  set cookie("user", user)
  set cookie("h", h)

Il vantaggio di questo è che l'utente non deve reinviare la propria password per aggiornare la difficoltà.

Ho implementato questo protocollo, ma non l'ho visto da nessun'altra parte. E la prima legge della criptodinamica è "Non farai mai rotolare te stesso".

Se funziona, mi piacerebbe vedere questo incorporato in un certificato per mostrare all'utente che il server memorizza i segreti dell'utente in modo responsabile.

    
posta powersupply 02.08.2017 - 23:33
fonte

2 risposte

2

Non sono un esperto qui, sto solo girando i miei pensieri da quando la tua idea è chiara e mi piacerebbe esplorarla.

Come sottolineato da @PwdRsch , la password14 parla [video] , [diapositive e codice di esempio] del 2014 (mentre non è il discorso più strong I 'ho mai visto) è esattamente su questo argomento.

Ho qualche problema con il tuo schema così com'è. Innanzitutto, per prevenire gli attacchi di replay dovresti davvero avere il server che genera un nonce per ogni accesso e inviarlo al client (poiché i nonce non hanno bisogno di essere key-strength, e non vuoi presentare un DoS facile, prendili da /dev/urandom anziché dal solito /dev/random )

In secondo luogo, sia l'utente malintenzionato che l'utente onesto devono eseguire il lavoro O (hash_prefix = '0000'), che sarà una penalità molto più grande per l'utente onesto sul proprio smartphone rispetto a quello che subirà l'utente malintenzionato. Attrezzatura per la pesca con GPU. Dare il vantaggio all'attaccante è brutto.

Risolviamoli facendo qualcosa del genere:

sul lato client:

h = "0"
d = "0000f"
hashed_pw = pbkdf2( password )
do: 
  h = hash (h + username + hashed_pw + nonce)
while (h > d)

send("login", username, h)

lato server:

listen("login", username, h)
user = database.get(username)
if "0000f" > hash (h + username + user.hashed_pw + nonce)
  send("accepted", true)
  session.user = user

Qui il server deve fare O (1) lavoro (una singola iterazione hash), il client onesto deve fare O (hash_prefix = '0000') lavoro, e l'attaccante deve fare un lavoro esponenziale nella lunghezza del server password: O (2 password_length-1 ) * O (hash_prefix = '0000').

Dopo aver indurito un po 'il tuo algoritmo (ma trascorrendo un'ora a fissarlo non significa affatto che sia pronto per prod), vediamo cosa sta ottenendo. Presumo che il tuo modello di minaccia sia quello di proteggere dagli attacchi brute-force online per impedire che gli account dei tuoi utenti vengano compromessi.

Frutto drive-by / low-hanging

In questo scenario di attacco l'aggressore sta cercando di trovare gli utenti abbastanza stupidi da usare una password su più comuni elenchi di password . Qui l'accelerazione esponenziale di forzare l'attaccante a indovinare la password scompare perché non indovina un numero esponenziale di password. Quindi per qualsiasi utente con una password debole, questo schema non sta facendo nulla perché pochi hash extra di hashing sono insignificanti per l'aggressore.

Attacchi mirati

Qui l'utente malintenzionato sta tentando di entrare in un account specifico . Se stanno davvero indovinando le password in modo casuale, allora questo li rallenterà, ma dato che il ritardo della rete e fail2ban rendono già un attacco di social engineering / phishing migliore di una brute-force online, non sono sicuro che tu stia aggiungendo valore anche qui. Abilita 2FA con Google Authenticator se sei preoccupato per questo.

In conclusione: l'idea è chiara e mi sono divertito a pensarci, ma

  1. Non sono sicuro che stia aggiungendo molto valore.
  2. "Non tirare il tuo". Ho trovato alcuni buchi nello schema, quindi avresti bisogno di dedicare molto tempo e sforzi per indurirlo prima che potessi essere sicuro di usarlo in produzione.
risposta data 03.08.2017 - 03:14
fonte
0

Penso che diverse parti del tuo piano variano in base all'utilità di "questo è un modo diverso di farlo ma non danneggerà nulla" a "questa è una grave vulnerabilità di sicurezza". In dettaglio:

Forse fuori dalla norma

Normalmente non ho hash la password lato client. Detto questo, penso che ci siano altre applicazioni là fuori che fanno hash lato client per motivi di prestazioni, quindi questo non è pazzesco. Tuttavia, penso che in questo caso hai fatto delle scelte in seguito al tuo hashing sul lato client che è cattivo.

Diversi, ma probabilmente di buon livello

Avere una funzione di lavoro in aumento è perfettamente normale e persino buono. L'idea è che con il passare del tempo aumenti il valore del lavoro nel tuo sistema per rendere più difficile la decifrazione delle password. Come evidentemente intendi, più "iterazioni" devi passare per costruire l'hash, più difficile è craccare una password, dal momento che qualsiasi tentativo di crack deve corrispondere al tuo numero di iterazioni. In termini di fare ciò, ci sono alcune considerazioni importanti qui:

1) (in realtà, un nitpick). L'hashing ripetuto in realtà non cambia affatto l'entropia. Alta entropia = più sicura, quindi se il tuo algoritmo sta diminuendo l'entropia (come hai detto nella tua risposta), sarebbe una brutta cosa. In entrambi i casi, la tua crescente funzione di lavoro non aumenta o diminuisce l'entropia.

2) Il problema con il tuo piano, perché fai le cose lato cliente, è che non puoi regolare la funzione di lavoro nel tempo per tenere conto dei progressi nella potenza di calcolo. Con il lato server è molto semplice aggiornare la funzione di lavoro nel tempo. Se si desidera rendere il cracking più costoso, è sufficiente ricalcolare l'hash della password con una funzione di lavoro superiore al successivo accesso dell'utente. Quindi, è possibile memorizzare sia la password che la funzione di lavoro nel database. Poiché il tuo server non vede mai la password, non puoi aggiornare l'hash senza ulteriore scambio tra client e server.

Foro di sicurezza potenzialmente grande

Questo è un problema gigantesco, penso:

set cookie("h", h)

Il problema è che stai inviando l'hash al client in un cookie. L'altra parte del problema è che il server accetta lo stesso hash direttamente per accedere all'utente. Pertanto, stai memorizzando in modo efficace la password dell'utente in un cookie, che è il posto meno sicuro di sempre. Qualcuno che è riuscito a rubare quel cookie sarebbe quindi in grado di accedere come utente fino a quando l'utente non cambia la sua password.

Normalmente l'unica cosa che memorizzi nel cookie è un ID di sessione, e sul lato server associ quell'ID di sessione con l'utente che ha effettuato l'accesso. Se l'id della sessione viene rubato (o si sospetta persino di essere stato compromesso), è possibile semplicemente invalidare l'ID della sessione. L'utente malintenzionato perde quindi tutti gli accessi e l'utente legittimo deve semplicemente accedere nuovamente.

Mai, in nessuna circostanza, memorizzare la password o l'hash della password in un cookie. Entrambi dovrebbero essere completamente dimenticati (lato client) dopo un login riuscito.

    
risposta data 03.08.2017 - 03:19
fonte

Leggi altre domande sui tag