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.