Utilizzo di SQL per confrontare le password con hash

-1

Impostazioni

Un sistema LAMP (Linux, Apache, MySQL, PHP). L'accesso a db avviene tramite l'interfaccia di loopback (forse non in futuro, dipende dalla soluzione di hosting).

Il db contiene una tabella con il nome utente, l'hash della password, la password con hash (e alcuni altri dati irrilevanti per questa discussione). L'utente DB per l'app ha solo il permesso di esecuzione, limitando l'accesso solo alle stored procedure.

Soluzione comune

Applicazioni PHP:

  1. Leggi salt e hashedPW utilizzando " select * from table where user=? "
  2. Hash ha immesso la password con salt e fa un confronto di stringhe in app a hashedPW da DB (so che password_hash e password_verify ora sono migliori, ma è ancora meglio?)
  3. Se le stringhe corrispondono, l'utente è autenticato.

La mia soluzione

Il database ha alcune stored procedure (SP) rilevanti per questa discussione:

  1. check_user(user, HTTP_USER_AGENT, REMOTE_ADDR) SP restituisce un view della tabella utenti che restituisce il sale solo se il nome utente viene trovato nella query.
  2. check_password(user, hashedPW, HTTP_USER_AGENT, REMOTE_ADDR) SP restituisce un codice di sessione univoco (che viene creato eseguendo un hashing debolmente una stringa casuale con i parametri del parametro HTTP_USER_AGENT + REMOTE_ADDR) se l'hash corrisponde o nulla se non lo è. questo codice di sessione viene quindi memorizzato in una variabile SESSION da utilizzare in ciascuna chiamata di stored procedure al DB per autenticare l'accesso.

Applicazioni PHP:

  1. controlla l'utente esistente nel sistema " call check_user(user, HTTP_USER_AGENT, REMOTE_ADDR) ".
  2. Se viene trovato user e l'indirizzo non è bloccato, DB registra la ricerca del nome utente, restituisce salt.
  3. Se REMOTE_ADDR è bloccato, registra e restituisce 0
  4. Hash ha immesso la password con sale e invia la stringa al DB utilizzando " call check_password(user, hashedPW, HTTP_USER_AGENT, REMOTE_ADDR) ".
  5. DB controlla la lista degli IP banditi, se username, remote_addr & Corrispondenza HTTP_USER_AGENT, DB registra l'autenticazione non riuscita, DB restituisce 0
  6. Se le stringhe corrispondono, il DB registra un'autenticazione corretta, DB restituisce i dati degli utenti nell'elenco.
  7. Se le stringhe non corrispondono, DB registra l'autenticazione non riuscita, DB restituisce 0.

Ragionamento

La mia soluzione consente:

  1. L'hash viene eseguito in PHP, che consente di eseguire più elaborazioni (cicli / cicli?) sull'hashing, algoritmi di hashing migliori (come Argon2).
  2. L'utente SQL può essere configurato con autorizzazioni limitate solo per eseguire stored procedure, in questo modo, anche se il nome utente e la password di connessione SQL vengono violati, può essere utilizzato solo per ottenere i dati forniti nelle stored procedure già nel DB e nient'altro, quindi non può ottenere un elenco completo di utenti e non può ottenere un elenco completo di hashedPW.
  3. Gli attacchi di forza bruta possono essere rilevati a livello di test del nome utente e fermati lì, richiedendo solo una chiamata DB per bloccare gli attacchi di forza bruta.
  4. Il client viene visualizzato come nome utente o password non validi, indipendentemente dal fatto che check_user o check_password non riescano.

Ci sono degli svantaggi in questa soluzione?

l'unico che riesco a vedere al momento è che non può usare [password_hash] che sembra essere il metodo preferito.

Ho esaminato le altre risposte a una domanda simile (qui: È una buona idea lasciare che un database faccia un controllo della password? e altrove), e la maggior parte delle persone afferma che l'hashing è fatto meglio nel codice PHP, per consentire il multi-threading (gestito da apache) e non legare il motore SQL con le cose per cui non è veramente progettato, quindi ho trovato il precedente ... tutti i feedback ricevuti con gratitudine.

PS ho appreso per la prima volta PHP circa 20 anni fa, ma non ho mai toccato questo o altri web dev in quasi 10 anni, quindi sii gentile.

    
posta Jim D 26.08.2018 - 14:42
fonte

1 risposta

0

Onestamente non vedo alcuna differenza dalla soluzione comune. Non hai rivelato i suoi svantaggi (e sì, password_hash e password_verify sono la soluzione comune), nessuno dei due ha fornito alcun beneficio per il tuo.

Alla fine il tuo approccio è quasi lo stesso di quello classico salvo per fare 2 chiamate al database contro uno e lanciare un sacco di cose non correlate.
Quindi suppongo che tu abbia appena pensato troppo. Mantieni la semplicità, non reinventare la ruota.

    
risposta data 11.09.2018 - 09:19
fonte

Leggi altre domande sui tag