Ho notato che la maggior parte dei siti invia le password come testo normale tramite HTTPS al server. C'è qualche vantaggio se invece di quello ho inviato l'hash della password al server? Sarebbe più sicuro?
Ho notato che la maggior parte dei siti invia le password come testo normale tramite HTTPS al server. C'è qualche vantaggio se invece di quello ho inviato l'hash della password al server? Sarebbe più sicuro?
Risposte:
Questa è una vecchia domanda, ma ho sentito il bisogno di fornire la mia opinione su questo importante argomento. C'è così tanta disinformazione qui
L'OP non ha mai menzionato l'invio della password in chiaro su HTTP - solo HTTPS, tuttavia molti sembrano rispondere alla domanda di inviare una password su HTTP per qualche motivo. Detto ciò:
Credo che le password non dovrebbero mai essere conservate (figuriamoci trasmesse) in testo normale. Ciò significa che non viene conservato su disco o anche in memoria.
Le persone che rispondono qui sembrano pensare che HTTPS sia un proiettile d'argento, ma non lo è. Certamente aiuta molto, tuttavia, e dovrebbe essere utilizzato in qualsiasi sessione autenticata.
Non c'è davvero bisogno di sapere cosa sia una password originale. Tutto ciò che è richiesto è un modo affidabile per generare (e rigenerare in modo affidabile) una "chiave" di autenticazione basata sul testo originale scelto dall'utente. In un mondo ideale, questo testo dovrebbe generare immediatamente una "chiave" eseguendo l'hashing utilizzando sale irreversibile. Questo sale dovrebbe essere univoco per la credenziale utente generata. Questa "chiave" sarà ciò che i tuoi sistemi useranno come password. In questo modo, se i tuoi sistemi verranno mai compromessi in futuro, queste credenziali saranno utili solo contro la tua stessa organizzazione e in nessun altro luogo in cui l'utente è stato pigro e ha utilizzato la stessa password.
Quindi abbiamo una chiave. Ora dobbiamo ripulire qualsiasi traccia della password sul dispositivo client.
Successivamente dobbiamo ottenere quella chiave per i tuoi sistemi. Non si dovrebbe mai trasmettere una chiave o una password "in chiaro". Nemmeno su HTTPS. HTTPS non è impenetrabile. In effetti, molte organizzazioni possono diventare un MITM affidabile, non dal punto di vista degli attacchi, ma per eseguire ispezioni sul traffico per implementare le proprie politiche di sicurezza. Questo indebolisce HTTPS e non è l'unico modo in cui accade (come ad esempio i reindirizzamenti agli attacchi HTTP MITM). Non dare mai per scontato che sia sicuro.
Per aggirare questo problema, abbiamo hash la chiave con un nonce una tantum. Questo nonce è unico per ogni invio di una chiave ai tuoi sistemi, anche per la stessa credenziale durante la stessa sessione se devi inviarla più volte. È possibile annullare questo nonce una volta arrivato nei propri sistemi per ripristinare la chiave di autenticazione e autenticare la richiesta.
A questo punto lo farei in modo irreversibile un'ultima volta prima che venga memorizzato in modo permanente nei tuoi sistemi. In questo modo puoi condividere le credenziali con le organizzazioni partner ai fini di SSO e simili, pur essendo in grado di dimostrare che la tua organizzazione non può impersonare l'utente. La parte migliore di questo approccio è che non condividi mai nulla generato dall'utente senza la sua autorizzazione.
Fai più ricerche, poiché c'è di più di quanto io abbia divulgato, ma se vuoi fornire una vera sicurezza ai tuoi utenti, penso che questo metodo sia attualmente la risposta più completa qui.
TL; DR:
Usa HTTPS. Password hash in modo sicuro, irreversibile, con un salt univoco per password. Fallo sul client: non trasmettere la password effettiva. La trasmissione della password originale dell'utente ai server non è mai "OK" o "Fine". Pulisci ogni traccia della password originale. Usa un nonce indipendentemente da HTTP / HTTPS. È molto più sicuro su molti livelli. (Risposta a OP).
Dal momento che è su HTTPS, va decisamente bene inviare la password senza hashing (su HTTPS non è testo in chiaro). Inoltre, se la tua applicazione dipende da HTTPS per mantenere i suoi contenuti protetti, allora è inutile hash la password prima di inviarla tramite HTTPS (cioè se un malintenzionato può decriptare i dati sul cavo, sei fottuto comunque)
No, in effetti questa sarebbe una vulnerabilità. Se l'attaccante è in grado di ottenere l'hash dal database, potrebbe usarlo per autenticarsi senza bisogno di crackarlo. In nessun caso un utente o un utente malintenzionato deve essere in grado di ottenere una password hash.
Lo scopo dell'hashing delle password è aggiungere un ulteriore livello di sicurezza. Se un utente malintenzionato è in grado di ottenere l'hash e il sale dal database utilizzando SQL Injection o un backup non sicuro, deve trovare il testo normale forzandolo. John The Ripper è comunemente usato per rompere gli hash delle password salate.
Il mancato utilizzo di https è una violazione della Top 10 di OWASP: protezione del livello di trasporto insufficiente A9
EDIT:
se nella tua implementazione calcoli un sha256(client_salt+plain_text_password)
e poi calcoli un altro hash sul lato server, sha256(server_salt+client_hash)
questa non è una grave vulnerabilità. Tuttavia, è ancora suscettibile di intercettare e riprodurre la richiesta. Quindi questa è ancora una chiara violazione di WASP A9. Tuttavia, questo utilizza ancora un digest del messaggio come livello di sicurezza.
La cosa più vicina che ho visto a una sostituzione lato client per https è un diffie-hellman nello scambio di chiavi in javascript . Tuttavia, questo impedisce gli attacchi MITM attivi e quindi è fino a tecnicismo una violazione di OWASP A9. Gli autori del codice concordano sul fatto che questo non è un sostituto completo per HTTPS, tuttavia è meglio di niente e meglio di un sistema di hashing lato client.
L'invio di un hash via cavo annulla completamente lo scopo dell'hash, perché un utente malintenzionato può semplicemente inviare l'hash e dimenticare la password. In poche parole, un sistema che autentica utilizzando un hash in chiaro è completamente aperto e può essere compromesso con nient'altro che lo sniffing della rete.
La password in testo non crittografato non lascia mai (nemmeno quando si utilizza HTTPS) il client. Deve essere sottoposto a hashing irreversibile prima di lasciare il client poiché non è necessario che il server conosca la password effettiva.
L'hash e quindi la trasmissione risolvono i problemi di sicurezza per gli utenti pigri che utilizzano la stessa password in più posizioni (lo so). Tuttavia, ciò non protegge la tua applicazione in quanto hacker che ha ottenuto l'accesso al database (o in qualsiasi altro modo è stato in grado di mettere le mani sull'hash) poiché l'hacker potrebbe semplicemente trasmettere l'hash e chiedere al server di accettarlo.
Per risolvere questo problema potresti ovviamente semplicemente eseguire l'hash dell'hash ricevuto dal server e chiamarlo un giorno.
Il mio approccio al problema in un'applicazione web basata su socket che sto creando è che alla connessione al client il server genera un salt (stringa casuale da aggiungere prima dell'hashing) e lo memorizza sulla variabile socket, quindi trasmette questo hash al cliente. Il client prende la password dell'utente, l'ha hash, aggiunge il sale dal server e l'hashing del tutto, prima di trasmetterlo al server. Quindi viene inviato al server che confronta questo hash con l'hash (hash nel DB + salt). Per quanto ne so questo è un buon approccio, ma per essere onesti non ho letto molto sull'argomento e se mi sbaglio su qualcosa mi piacerebbe essere corretto :)
Usa HTTP Digest: protegge la password anche su http (ma il miglior utilizzo sarebbe http digest su https)
Wikipedia:
L'autenticazione dell'accesso al digest HTTP è uno dei metodi concordati che un server Web può utilizzare per negoziare le credenziali con un utente Web (utilizzando il protocollo HTTP). L'autenticazione del digest ha lo scopo di sostituire l'uso non crittografato dell'autenticazione di accesso di base, consentendo di stabilire in modo sicuro l'identità dell'utente senza dover inviare una password in chiaro sulla rete. L'autenticazione del digest è fondamentalmente un'applicazione di hashing crittografico MD5 con l'utilizzo di valori nonce per prevenire la crittoanalisi.
Collegamento: http://en.wikipedia.org/wiki/Digest_access_authentication
Se vuoi vedere un utilizzo "nella vita reale", potresti guardare phpMyID - un provider php openid che utilizza l'autenticazione http digest http://siege.org/phpmyid.php
.. oppure puoi iniziare dagli esempi di autenticazione php su http://php.net/manual/en/features.http-auth.php
Http digest rfc: http://www.faqs.org/rfcs/rfc2617
Dai miei test tutti i browser moderni lo supportano ...
Se stai cercando di sostituire una password in chiaro su HTTPS con una password con hash su HTTP, stai cercando problemi. HTTPS genera una chiave di transazione condivisa casuale quando si apre un canale di comunicazione. È difficile da decifrare, poiché sei praticamente limitato alla forzatura bruta della chiave condivisa utilizzata per una transazione (relativamente) a breve termine. Mentre il tuo hashish può essere semplicemente annusato, portato fuori linea e guardato in alto in un tavolo arcobaleno o semplicemente forzato per un lungo periodo di tempo.
Tuttavia, un offuscamento della password lato client di base (non hash) inviato tramite HTTPS ha qualche valore. Se non sbaglio questa tecnica è effettivamente utilizzata da alcune banche. Lo scopo di questa tecnica non è proteggere la password dallo sniffing attraverso il cavo. Piuttosto, è per impedire che la password sia utilizzabile per stupidi strumenti di spionaggio e plug-in del browser che catturano ogni richiesta HTTPS GET / POST che vedono. Ho visto un file di registro acquisito da un sito Web dannoso che conteneva 400 MB di transazioni GET / POST casuali acquisite dalle sessioni utente. Puoi immaginare che i siti Web che utilizzavano solo HTTPS vengano visualizzati con password in chiaro nel registro, ma anche i siti Web con un offuscamento molto semplice (ROT13) vengono visualizzati con password che non sono immediatamente utilizzabili.
Se sei connesso a un server https, il flusso di dati tra il server e il browser dovrebbe essere crittografato. I dati sono solo testo normale prima di essere inviati e dopo essere stati ricevuti. Articolo di Wikipedia
Dichiarazione di non responsabilità: non sono affatto un esperto di sicurezza e sto postando con la speranza che altri critichino la mia posizione come eccessivamente cauta o migliorabile e imparerò da essa. Detto questo, voglio solo sottolineare che l'hashing quando lascia il tuo client non significa che non devi fare l'hash sul back-end prima di inserirlo nel database.
Fai entrambi
Fai entrambe le cose perché:
L'hashing durante il viaggio aiuta a coprire le vulnerabilità del trasporto, se la connessione SSL è compromessa, non possono ancora vedere la password grezza. Non importa in termini di capacità di impersonare utenti autorizzati, ma proteggerà i tuoi utenti dal vedere le loro password lette insieme alla loro email. La maggior parte delle persone non segue le migliori pratiche e utilizza la stessa password per molti dei propri account, quindi questa può essere una grave vulnerabilità per i tuoi visitatori.
Se qualcuno, in qualche modo, è stato in grado di leggere le password dal database (questo accade, pensa SQL injection), non sarà comunque in grado di eseguire azioni privilegiate che impersonano gli utenti tramite la mia API. Ciò è dovuto all'asimmetria hash; anche se conoscono l'hash memorizzato nel tuo DB, non conosceranno la chiave originale usata per crearlo ed è quello che il tuo middleware di autenticazione usa per autenticarsi. Questo è anche il motivo per cui dovresti sempre salare il tuo deposito di hashish.
Certo, potrebbero fare molti altri danni se avessero libero sfogo per leggere ciò che vogliono dal tuo database.
Voglio solo sottolineare qui che se decidi di eseguire l'hashing della chiave prima della partenza dai tuoi clienti, non è sufficiente: l'hashing back-end è, imo, molto più importante ed è per questo: se qualcuno sta intercettando il traffico dal tuo client, quindi vedranno il contenuto del password
campo. Che si tratti di un hash o di un testo semplice, non importa: possono copiarlo alla lettera per impersonare un client autorizzato. (A meno che tu non segua i passaggi descritti da @ user3299591 e ti consiglio di farlo). L'hashing della colonna DB, d'altra parte, è una necessità e per nulla difficile da implementare.
SSL / TLS non sta sostituendo il nonce? Non vedo un valore aggiunto in questo dato che SSL / TLS protegge anche dagli attacchi di replay.
In realtà sarebbe meno sicuro eseguire l'hash della password e inviarla su un canale non crittografato. Esponerai il tuo algoritmo di hashing sul client. Gli hacker potrebbero semplicemente annusare l'hash della password e quindi usarlo per hackerare in un secondo momento.
Utilizzando HTTPS, impedisci a un hacker di ottenere la password da un'unica fonte, poiché HTTPS utilizza due canali, entrambi crittografati.
Se c'è un vantaggio e se è più (o meno) sicuro dipende davvero dall'implementazione. C'è probabilmente qualche vantaggio, ma se lo implementi male, potresti sicuramente creare una soluzione meno sicura rispetto al passaggio anche di una password in chiaro.
Questo può essere visto dalla prospettiva di due tipi di attacchi: uno con accesso al traffico di rete e un altro con accesso al database.
Se il tuo aggressore è in grado di intercettare la versione in testo normale del traffico di rete, vedere un hash della password è più sicuro che vedere la password in chiaro. Sebbene l'attaccante possa ancora accedere al tuo server utilizzando quell'hash, richiederebbe un crack a forza bruta (a volte pre-calcolato) di quell'hash per determinare la password che potrebbe essere utile su altri sistemi. Le persone dovrebbero utilizzare password diverse su sistemi diversi, ma spesso non lo fanno.
Se un utente malintenzionato ha ottenuto l'accesso al database, magari tramite una copia di un backup, è necessario assicurarsi che non si possa accedere solo con quella conoscenza. Se, ad esempio, hai memorizzato un hash salato con il nome di accesso come hash(login_name+password)
e hai passato lo stesso hash dal client per il confronto diretto, l'attaccante potrebbe scegliere un utente a caso, inviare l'hash letto dal database e accedere come quell'utente senza conoscere la password, aumentando la portata della violazione. In tal caso, l'invio della password in chiaro sarebbe stato più sicuro perché l'aggressore avrebbe avuto bisogno di conoscere il testo in chiaro per poter accedere, anche avendo una copia del database. È qui che l'implementazione è fondamentale. Indipendentemente dal fatto che invii una password in testo normale o un hash lato client di quella password, dovresti eseguire l'hash del valore sul lato server e confrontare tale hash con l'hash memorizzato nel record dell'utente.
Concetti da tenere a mente: