Domanda:
Come proteggere le password su HTTP?
FireCubez
2018-11-09 19:57:16 UTC
view on stackexchange narkive permalink

Supponiamo che la mia password sia abc . Voglio inviarlo al server tramite HTTP.

Potrei inviarlo in testo normale e lasciare che il server lo abbia hash e confrontarlo con le voci nel suo database, ma poi chiunque può vedere il traffico su quella connessione vedrebbe la password in testo normale.

Quindi potrei eseguire l'hashing lato client e lasciare che il server lo confronti senza hashing poiché è già hash (o il server potrebbe anche raddoppiare l'hash, ma nessuna differenza questa situazione). Ma poi di nuovo chiunque sia in grado di vedere il traffico vedrebbe la password con hash, quindi invierà la password con hash al server e il server la accetterebbe.

Come invio le password su HTTP? Devo implementare un algoritmo di crittografia come la crittografia a chiave pubblica RSA? O è impossibile?

Il metodo dovrebbe essere utilizzabile in qualsiasi browser.

Perché non puoi usare semplicemente TLS?Non c'è davvero altro modo per farlo in modo sicuro.
@AndrolGenhald Potrei, questa è solo una prova di concetto.Se non c'è altro modo per farlo in modo sicuro, questa è la risposta che stavo cercando.Dovresti pubblicarlo come risposta
Non hai bisogno di TLS nativo - potresti, in teoria, implementare TLS su HTTP - ma non sarebbe neanche lontanamente pratico.
@AndrolGenhald Non ci sono buone ragioni per non usare TLS, ma credo che ci siano molti altri modi per farlo in modo sicuro.Ad esempio, è possibile eseguire il tunneling di http tramite ssh.
Forse provare a utilizzare ECDHE per scambiare le chiavi in modo sicuro?
@emory Il poster ha chiarito che il contesto è il browser Web alla comunicazione del server HTTP, non l'applicazione personalizzata al server personalizzato.
È un problema reale che stai affrontando o solo un esperimento mentale?
@whatsisname Ho affermato che in un commento precedente, è solo un esperimento
Anche se odio quando chiedi ad A e le persone rispondono "usa solo B", dovrò essere d'accordo con le molte risposte "usa solo TLS" poiché questo è il modo più semplice per un problema pratico.Ora hai affermato che _non_ riguarda un problema pratico ma "solo per esperimento", quindi potresti voler leggere i [protocolli a conoscenza zero] (https://en.wikipedia.org/wiki/Zero-knowledge_proof) che fanno cosatu vuoi.
L'implementazione della password di MSN Messenger originale si adattava a questo scenario.Il server ti ha inviato un "salt" e tu hai cancellato la tua password usando quello e hai inviato l'hash al server.Poiché il server conosceva la tua password, potrebbe eseguire lo stesso calcolo.Il server era responsabile di assicurarsi che non riutilizzasse i sali
FWIW, anche se riesci a trasferire le password in modo sicuro, non avrai ottenuto nulla.Il resto della sessione non è crittografato, può essere facilmente rubato o modificato.Anche se puoi dimostrare in modo sicuro "Sei Bob", nel momento in cui ciò accade, Alice può rubare la tua sessione ed "essere Bob" per tutto il tempo che vuole.
@curiousguy Se OP ha eseguito `ssh -L 127.0.0.1:8080:intra.example.com:80 gw.example.com` quindi ha navigato su http://127.0.0.1:8080, la connessione sarà crittografata e le password protette.(1) Ciò presuppone che OP possa eseguire ssh in gw.example.com e (2) forse il server web non risponde alle richieste locali.Questo esempio potrebbe / potrebbe non funzionare per OP, ma l'affermazione che TLS è l'unico modo è sbagliata.
@emory Non è _in effetto_ che si usa TLS, ma basta che `ssh` lo faccia invece di implementarlo direttamente nel client?E la connessione da `gw.example.com` al vero server web non sarebbe ancora vulnerabile alle intercettazioni?
@TripeHound Consiglierei di usare solo TLS e di non preoccuparmi di questi problemi.Ma se in effetti utilizza TLS ma lo fa ssh invece di implementarlo direttamente nel client, la connessione al server web reale non sarebbe vulnerabile alle intercettazioni.
Nove risposte:
tim
2018-11-09 20:08:48 UTC
view on stackexchange narkive permalink

Non puoi.

Per inviare informazioni in modo sicuro su un canale non protetto, è necessaria la crittografia.

La crittografia simmetrica è fuori uso, perché dovresti prima trasportare la chiave, cosa che non puoi fare in modo sicuro su un canale non protetto [*].

Questo ti lascia con la chiave pubblica crittografia. Ovviamente potresti tirare il tuo, ma non vuoi essere un Dave, quindi è fuori, il che ti lascia con HTTPS.

[*] Puoi ovviamente provare a utilizzare un canale sicuro per scambiare la chiave, ad esempio lo scambio fisico di una chiave. Quindi puoi utilizzare la crittografia a chiave segreta, come Kerberos.

Non potresti farlo due volte?Una volta sul lato client, una volta sul server?
@NathanMerrill - [L'hashing della password sul lato client rende l'hash la password] (https://security.stackexchange.com/questions/8596/https-security-should-password-be-hashed-server-side-or-lato client) (assente qualche schema per includere informazioni extra).Tuttavia, solo proteggere la password è inutile: devi almeno autenticare il ** canale **, altrimenti un utente malintenzionato può impersonare entrambe le estremità della conversazione, anche senza conoscere la password.
Questo è fuorviante.Si, puoi.Questa domanda chiede come proteggere le password quando non è possibile utilizzare HTTP.Una cattiva politica aziendale, un firewall configurato in modo errato possono forzare l'uso di HTTP.In situazioni come questa, lo scambio di certificati (IPsec TLS SCRAM ecc.) Tramite un canale laterale è possibile e dovrebbe essere la risposta.Rispondi alla domanda invece di dare consigli che non erano richiesti.
@noɥʇʎԀʎzɐɹƆ Ho menzionato che ci sono alternative quando può essere usato un canale laterale sicuro (che è richiesto per le alternative menzionate in altre risposte).Ma non è proprio di questo che si tratta ("Il metodo dovrebbe essere utilizzabile in qualsiasi browser").Ci sono sicuramente casi d'uso per queste alternative, ma "non possiamo usare HTTPS perché la nostra infrastruttura è troppo rotta" non dovrebbe essere uno di questi.
Sono d'accordo con il punto principale: non può essere fatto.Ma aggiungerei che anche se sei Dave e rotoli la tua crittografia, non sarebbe d'aiuto.Il codice che esegue la crittografia viene fornito tramite HTTP e può quindi essere manomesso.
AndrolGenhald
2018-11-09 20:09:53 UTC
view on stackexchange narkive permalink

TLS è davvero l'unico modo per farlo.

Ma cosa succede se lo crittografo con JavaScript?

L'autore dell'attacco può modificare il JavaScript tu inviare al client, o semplicemente iniettare il proprio JavaScript che registra tutte le informazioni inserite.

Quindi userò CSP e SRI per impedire l'aggiunta di script e la modifica dei miei script.

Sono contento che tu stia utilizzando strumenti moderni per proteggere il tuo sito, ma SRI in un contesto non protetto in realtà protegge solo dalla compromissione di una risorsa esterna. Un utente malintenzionato può semplicemente modificare le intestazioni CSP e i tag SRI.

Non c'è davvero alcun modo per farlo senza utilizzare la crittografia dall'inizio e l'unico modo standard per farlo è usare TLS.

Melanie
2018-11-10 00:01:01 UTC
view on stackexchange narkive permalink

Anche se accetto che dovresti utilizzare HTTPS, puoi renderlo ancora più sicuro utilizzando il Salted Challenge Response Authentication Mechanism (SCRAM, vedi RFC 5802) per l'effettivo scambio di autenticazione.

Non è banale da implementare, ma il succo è che, invece di inviare la password al server, invii una prova al server che conosci la password. Dal momento che derivare la prova utilizza un nonce dal client e dal server, non è qualcosa che può essere riutilizzato da un utente malintenzionato (come sarebbe l'invio dell'hash stesso).

Questo ha alcuni vantaggi aggiuntivi nell'usare HTTPS con l'autenticazione di base che descrivi:

  1. Il server non vede mai la tua password durante l'accesso. Se qualcuno è riuscito a inserire codice dannoso nel server, non saprà comunque quale sia la tua password .
  2. Se è presente un bug nell'implementazione HTTPS (pensa a Heartbleed), gli aggressori non saranno comunque in grado di acquisire la tua password. Perché, anche una volta che TLS viene bypassato, la password non è disponibile.
  3. Se, per qualche motivo, non puoi usare HTTPS, è meglio che inviare la password in chiaro. Un utente malintenzionato non sarà in grado di indovinare la tua password in base allo scambio. Detto questo, dovresti comunque utilizzare HTTPS, perché la difesa in profondità è migliore.

Tieni presente che questo è sicuro solo se il client è in grado di eseguire lo SCRAM calcoli senza scaricare codice dal server. Potresti fornire un client grasso o gli utenti potrebbero essere in grado di scrivere il proprio codice che controllano. Scaricare il codice SCRAM su HTTP darebbe a un utente malintenzionato l'opportunità di modificare il codice SCRAM per inviare la password in chiaro o per esporla in altro modo.

Puoi farlo in sicurezza con un fat client (un'applicazione desktop o mobile) distribuito in modo sicuro.Tuttavia, con un thin client nel browser, il codice client stesso viene consegnato anche tramite HTTP e, come sottolineato da @AndrolGenhald, gli aggressori nel mezzo possono intercettarlo e modificarlo per inviare loro la password.
@Zoltan È molto vero, grazie per il chiarimento.La domanda originale non specifica se hanno bisogno di un cliente magro o grasso, quindi la mia risposta non si applicherebbe in tutti i casi.Ma anche su HTTP, penso che questo fornisca una sicurezza aggiuntiva.L'attacco è passato dallo spionaggio del traffico alla modifica del codice.Niente di insormontabile, quindi non sarebbe sicuro, ma forse meno grave?E penso che avere sia HTTPS che SCRAM sia molto vantaggioso.
Se sei d'accordo, potresti considerare di menzionare questa restrizione nella tua risposta.Altrimenti mi piace molto la tua risposta in quanto anche la risposta alla sfida è stato il mio primo pensiero e nessuna delle altre risposte lo ha menzionato.
Grazie, ho aggiornato la mia risposta.Fammi sapere se pensi che potrebbero servire ulteriori chiarimenti!
Mi sembra buono, grazie, voto positivo.Tuttavia, dovresti rimuovere la parte "Grazie a Zoltan", poiché frasi di cortesia come saluti, firme e ringraziamenti sono sconsigliate nelle domande e nelle risposte sui siti di Stack Exchange per concentrarsi sul contenuto.Oh, e comunque benvenuto in Stack Exchange!:)
@Melanie Hai assolutamente ragione sul fatto che anche con solo HTTP è meglio.Ci sono attaccanti capaci solo di attacchi passivi.Detto questo, non c'è motivo di non utilizzare HTTPS al giorno d'oggi quando è gratuito.
SCRAM richiede che la password sia memorizzata in modo recuperabile sul server?O può ancora essere salato + hashish
@IanF1 Il server deve solo conoscere un hash della password.Inoltre, tutti i browser che conosco implementano un meccanismo simile: [HTTP Digest Authentication] (https://en.wikipedia.org/wiki/Digest_access_authentication), quindi anche con un thin client è possibile utilizzare questo metodo.D'altra parte, HTTP digest si basa sugli obsoleti hash MD5, ma non sono sicuro di quanto sia insicuro a causa di ciò (MD5 non è rotto per ogni applicazione).
@Zoltan, Ho rimosso il ringraziamento.Anche se non mi piace non dare credito dove è dovuto, suppongo sia qui nei commenti.Grazie ancora!
@Jost L'uso di MD5 (o una funzione basata sull'iterazione di MD5, o la composizione con un sale o un nome) per archiviare o controllare le password ** non è più rotto oggi di quanto non sia mai stato **: il calcolo di MD5 o qualsiasi iterazione di MD5 può "t essere semplificato e MD5 ^ 1000 necessita ancora di 1000 iterazioni del calcolo, e non c'è modo migliore per trovare quale x soddisfa MD5 ^ 1000 (x) = y che provare diversi valori di x, o metodi basati su elenchi precalcolati, che èanche il metodo migliore per SHA1 o funzioni hash più moderne.Nessun progresso teorico o pratico è stato fatto qui.
Polynomial
2018-11-10 00:31:25 UTC
view on stackexchange narkive permalink

In questo caso dovresti assolutamente distribuire TLS.

Se decidi di inventare un sistema di sicurezza del trasporto su HTTP, alla fine finirai per implementare comunque un sottoinsieme della funzionalità TLS. Ci sono molte insidie ​​di cui essere consapevoli quando si progetta e si implementa un tale sistema, che vengono ulteriormente amplificate quando si sceglie di provare a implementare il sistema con un linguaggio che non offre molte funzionalità di sicurezza.

Anche se hai implementato una corretta implementazione di un protocollo crittografico in JavaScript (che è già una grande sfida) non puoi fare affidamento sul fatto che l'implementazione sia resistente agli attacchi temporali, e il tutto si interrompe se qualcuno ha gli script disabilitati (ad esempio con NoScript).

Come regola generale, dovresti scegliere l'implementazione che consiste dei componenti più semplici, ben compresi e affidabili che richiedono di scrivere la minor quantità di codice critico per la sicurezza. Per citare Andrew Tannenbaum:

Un numero sostanziale di problemi (nella sicurezza delle applicazioni) sono causati da software difettoso, che si verifica perché i fornitori continuano ad aggiungere sempre più funzionalità a i loro programmi, il che significa inevitabilmente più codice e quindi più bug.

Brian Williams
2018-11-09 22:03:34 UTC
view on stackexchange narkive permalink

Devo implementare un algoritmo di crittografia come la crittografia a chiave pubblica RSA?

Se stai pensando di provarlo, potresti anche fare il massimo e usare HTTPS. Dal momento che non sembri un esperto, la crittografia "rotolare la tua" avrà senza dubbio implementazioni errate che la rendono insicura.

Pierre del Perugia
2018-11-10 15:38:45 UTC
view on stackexchange narkive permalink

In realtà è del tutto possibile.

La password deve essere hash sul lato client, ma non con una funzione statica. Il metodo seguente utilizza due passaggi ed è ispirato all ' autenticazione dell'accesso al digest:

NOTA: il server conserva un HMAC della password e la corrispondente Key ( Digest );

  1. Il client inizia richiedendo un nonce al server, il server restituisce la Key e il Nonce”;
  2. Client calcola: HMAC (HMAC ( Password , Chiave ), Nonce ) e lo invia al server;
  3. Il server calcola: HMAC ( Digest , Nonce ) e lo confronta con il valore ricevuto.

Questo ti protegge dalla riproduzione.

L'interesse principale che vedo non è una protezione dalle intercettazioni, ma per essere completamente sicuro che la password in chiaro non verrà memorizzata su il server, nemmeno in un registro di sistema (vedi Twitter o GitHub).

Nota: HMAC può essere sostituito da PBKDF2.

Quindi qualche utente malintenzionato può iniettare del codice per ottenere la password direttamente da "".Un'idea folle: "Purtroppo è * solo un po '* difficile supportare HTTPS su indirizzi IP riservati. Per favore [esegui questo codice sul tuo terminale] (https://stackoverflow.com/a/7285256) e incolla il risultato HMAC erano. "(ovviamente disabilitare il copia incolla per evitare il pastejacking a lungo termine).
CBHacking
2018-11-10 16:42:21 UTC
view on stackexchange narkive permalink

Esiste effettivamente un modo per autenticare un utente su una connessione non sicura: protocollo SRP (Secure Remote Password). SRP è progettato specificamente per consentire a un client di autenticarsi su un server senza che un utente malintenzionato Man-in-the-Middle sia in grado di catturare la password del client o persino di riprodurre l'autenticazione per impersonare in seguito il client, indipendentemente dal fatto che l'autenticazione sia riuscita o meno. Inoltre, l'autenticazione riuscita con SRP crea una chiave segreta condivisa che sia il client che il server conoscono, ma un MitM no. Questa chiave segreta potrebbe essere utilizzata per la crittografia simmetrica e / o HMAC.

Tuttavia, ci sono una serie di limitazioni di SRP:

  1. L'utente deve essersi registrato in alcuni moda, poiché il processo di registrazione richiede la trasmissione di materiale equivalente a una password (sebbene il server non abbia bisogno di memorizzarlo).
  2. Sebbene sia sicuro tentare un accesso SRP con un server non affidabile (cioè, non esporrà la tua password a quel server e sarai in grado di dire che il server non aveva la tua password nel suo database), Non è sicuro caricare una pagina web di accesso da un server non attendibile (potrebbe inviare una pagina che cattura ogni tua battitura e la invia da qualche parte).
  3. Sebbene l'autenticazione riuscita tramite SRP generi una chiave segreta condivisa sicura, il codice per utilizzare effettivamente questa chiave in un'app Web dovrebbe essere caricato da un server e un utente malintenzionato potrebbe manomettere il codice per rubare la chiave simmetrica e apportare modifiche alle richieste e alle risposte.

In altre parole, mentre SRP può essere utile in situazioni in cui hai un client fidato che non ha bisogno di scaricare il suo codice su una connessione non sicura e hai anche qualche altro modo sicuro per registrare gli utenti, SRP non è adatto per un'applicazione web. Le app Web scaricano sempre il loro codice dal server, quindi se la connessione al server non è sicura, un MitM (o un altro aggressore di rete, ad esempio qualcuno che falsifica DNS) può iniettare codice dannoso nell'app Web e non c'è niente che tu, la vittima, può fare al riguardo. Una volta che il codice è presente, può acquisire qualsiasi password o altri dati immessi, rubare qualsiasi chiave generata e manomettere le richieste inviate o le risposte che ricevi senza che tu lo sappia.

Christopher Schultz
2018-11-11 04:51:56 UTC
view on stackexchange narkive permalink

È certamente possibile inviare una password in modo sicuro utilizzando HTTP. C'è anche uno standard per questo. Si chiama HTTP-Digest ed è definito in RFC 7616. Fa parte delle specifiche HTTP da un po 'di tempo. Originariamente era stato progettato per utilizzare solo l'algoritmo MD5 message-digest ("hashing"), ma le revisioni successive dello standard consentono al client e al server di negoziare quale algoritmo utilizzare.

Sfortunatamente, ci sono molti problemi con HTTP-digest e il più lampante è che il server deve avere la password in chiaro . Pertanto, sebbene sia possibile comunicare le password in modo sicuro utilizzando HTTP, non è possibile archiviare in modo sicuro le password sul server mentre lo si utilizza. Quindi, fondamentalmente, non è utile.

Come altri hanno detto, sarebbe meglio implementare TLS perché risolve più problemi contemporaneamente ed è abbastanza compatibile con le versioni future.

Richard N
2018-11-13 03:55:03 UTC
view on stackexchange narkive permalink

Come altri hanno detto TLS! TLS! TLS! (e anche con una lunghezza di chiave decente)

Ma se devi usare HTTP e qualsiasi server per l'implementazione, è per uso programmatico o per uso umano? Se per uso umano, stai guardando l'autenticazione di base o basato sulla forma? E i tuoi usi sono in grado di applicare un po 'di logica? non può essere usato da Joe public. È necessario proteggere qualcos'altro o solo la password stessa?

In tal caso potresti essere in grado di guardare:

  • Usa un pad / generatore di password una tantum (i telecomandi RSA non sono economici e se hai quel tipo di denaro da spendere puoi permetterti TLS)
  • Qualche altra autenticazione a 2 fattori come gli SMS (non senza i propri problemi).
  • Un semplice meccanismo di sfida / risposta per offuscare la password, ad esempio la pagina mostra due numeri nel testo (nemmeno etichettati in modo sfacciato), l'utente deve iniziare la password con un calcolo semplice come la differenza tra i due numeri aggiunti a ciascuna cifra di un PIN, magari con elementi casuali prima e / o dopo, ad esempio 98634572dkkgdld. La modifica dei numeri di sfida dovrebbe interrompere gli attacchi di replay che non vengono provati immediatamente, ma se un utente malintenzionato riesce a catturare un numero sufficiente di tentativi, potrebbe essere in grado di risolverlo. Non puoi inserire alcuna logica di offuscamento negli script rivolti agli utenti, perché sarà visto e se lo schema è troppo complesso i tuoi utenti ti odieranno ancora di più.

Io ancora così con TLS, tuttavia, i certificati sono economici (anche gratuiti) in questi giorni, quindi gli schemi di offuscamento contorti non hanno davvero motivo di esistere più.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 4.0 con cui è distribuito.
Loading...