Autenticazione HTTP con bcrypt fatto bene

2

Ho un'app per Android che si connette a un server tramite HTTP (nota l'assenza di S, anche Android significa Java, quindi niente di quello che farò con hardcode nella mia app sarà irraggiungibile).

Voglio memorizzare la password in modo sicuro sul mio DB, quindi volevo usare bcrypt (con password e salt)

Il mio problema è il seguente: poiché sono su HTTP, non voglio inviare la password semplice al mio server.

Dato che sono mobile e il 3G è molto lento, non voglio mandare il sale al telefono per poter inviare la password già cancellata al server. (due query invece di una)

C'è un modo per farlo funzionare oltre a usare il login + una stringa fissa come un sale?

Grazie!

    
posta Taiko 23.07.2014 - 12:36
fonte

2 risposte

2

Vuoi usare bcrypt per l'archiviazione sul lato server: va bene. Devi ricordare perché lo fai: è perché teme che l'area di memoria del server possa essere saccheggiata in qualche modo, e vuoi un ulteriore livello di protezione. Il punto di bcrypt (o qualsiasi altra simile funzione di hashing della password ) è quello di rendere gli attacchi di dizionario più costosi: c'è un sale (per prevenire attacchi paralleli su molte password hash e precomputazioni), e ci sono molte iterazioni (per rendere ogni ipotesi costosa).

Quindi vuoi massimizzare il numero di iterazioni. Ciò implica che l'hashing deve essere fatto su un computer fast . Uno smartphone con codice Java non è veloce (una versione Android abbastanza recente include una macchina virtuale Java con un compilatore JIT che offrirà una velocità non troppo patetica, ma il risultato sarà comunque non competitivo con le capacità del server). Pertanto, si desidera veramente che il bcrypt si verifichi sul lato server. Anche se ottenere il sale dal server era accettabile (dal punto di vista della latenza della rete), la mancanza di prestazioni della CPU sul lato client sarebbe debilitante.

Pertanto, il tuo problema riguarda davvero come trasferire informazioni molto sensibili (la password) dallo smartphone al server, assicurandoti che non venga intercettato durante il transito. Dal momento che un'app non può contenere segreti (perché il reverse engineering funziona, e non è esclusivo di Java), dovrai usare crittografia asimmetrica , con una coppia di chiavi pubblica / privata, in modo tale che il server possieda la chiave privata e il client possa assicurarsi che utilizzi la chiave pubblica destra (e non una falsa chiave controllata da attaccante ). A quel punto, sei molto vicino a SSL.

Utilizzare HTTPS sarebbe il metodo più semplice per ottenere ciò che cerchi; in particolare perché il telefono include già tutto il codice necessario.

Si potrebbe sostenere che HTTPS implichi troppi round-trip di rete. È concettualmente possibile fare di meglio quando ciò che si desidera è una trasmissione a senso unico di alcuni dati segreti sul server; in tal caso, puoi imitare il modello di email, che quindi punta a OpenPGP . È possibile crittografare in modo asimmetrico la password da inviare, utilizzando la chiave pubblica PGP del server noto (codificata nell'app, che non è un problema, è una chiave pubblica ) e inviando il risultato come un singolo HTTP richiesta. Ciò minimizza il traffico di rete, pur facendo affidamento su un formato di crittografia che è sopravvissuto a una certa quantità di revisione esterna. Una ricerca su Google su "libreria android openpgp" fornisce alcuni utili suggerimenti per l'implementazione effettiva.

    
risposta data 23.07.2014 - 14:45
fonte
0

Ciò che stai proponendo non è ancora sicuro: poiché il sale è sempre lo stesso per un determinato account, un utente malintenzionato che ascolta il traffico può semplicemente registrare il valore restituito dal client e riutilizzarlo in seguito (questa è la chiamata "< a href="http://en.wikipedia.org/wiki/Pass_the_hash"> passando l'hash ").

Ci sono modi per aiutare a mitigare quel problema, ma alla fine tutti finiscono con lo stesso problema: si può proteggere l'accesso ma tutto il resto (incluso il meccanismo che si usa per mantenere lo stato della sessione lato server) è ancora insicuro e finisci con un modello di sicurezza completamente rotto.

Quindi, per favore, non provate a farlo da soli: il vostro problema è vecchio e ha una soluzione facile da implementare, facile da implementare, ampiamente supportata ed economica: usate HTTPS.

    
risposta data 23.07.2014 - 14:33
fonte

Leggi altre domande sui tag