Come proteggere le password su HTTP?

26

Dì che la mia password è abc . Voglio inviarlo al server su HTTP.

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

Quindi potrei farlo sul lato client e lasciare che il server lo paragoni senza hashing dato che è già sottoposto a hash (o il server potrebbe persino duplicare l'hash, ma nessuna differenza in questa situazione). Ma poi di nuovo chiunque veda il traffico vedrebbe l'hash della password, quindi invia la password con hash al server e il server lo accetterà.

Come posso inviare 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.

    
posta FireCubez 09.11.2018 - 14:57
fonte

10 risposte

109

Non puoi.

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

La crittografia simmetrica non è disponibile, perché prima dovresti trasportare la chiave, che non puoi eseguire in modo sicuro su un canale non sicuro [*].

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

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

    
risposta data 09.11.2018 - 15:08
fonte
46

TLS è davvero l'unico modo per farlo.

Ma se lo criptassi con JavaScript?

L'utente malintenzionato può modificare il codice JavaScript che invii al client o semplicemente inserire il proprio codice 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 non -contesto sicuro protegge solo contro il compromesso 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 usare la crittografia dall'inizio e l'unico modo standard per farlo è usare TLS.

    
risposta data 09.11.2018 - 15:09
fonte
26

Anche se sono d'accordo sul fatto che dovresti usare HTTPS, puoi renderlo ancora più sicuro usando il meccanismo di autenticazione della risposta alla risposta salata (SCRAM, vedi RFC 5802 ) per lo scambio di autenticazione effettivo.

Non è banale da implementare, ma il succo è che, anziché inviare la password al server, si invia una prova al server che si conosce la password. Dal momento che derivare la dimostrazione usa un nonce dal client e dal server, non è qualcosa che può essere riutilizzato da un utente malintenzionato (come se fosse l'invio dell'hash stesso).

Questo ha alcuni vantaggi aggiunti all'utilizzo di HTTPS con l'autenticazione di base che descrivi:

  1. Il server non vede mai realmente la tua password quando accedi. Se qualcuno è riuscito a inserire codice dannoso sul server, non saprà ancora quale sia la tua password.
  2. Se c'è un bug nell'implementazione HTTPS (pensa Heartbleed), gli hacker continueranno a non essere in grado di acquisire la tua password. Perché, anche una volta che la TLS è stata ignorata, la password non è disponibile.
  3. Se, per qualche motivo, non puoi utilizzare HTTPS, è meglio che inviare la password in chiaro. Un utente malintenzionato non sarà in grado di indovinare la password in base allo scambio. Detto questo, dovresti comunque utilizzare HTTPS, perché la difesa in profondità è migliore.

Nota che è sicuro solo se il client è in grado di eseguire i calcoli SCRAM senza scaricando codice dal server. Potresti fornire un fat client, o gli utenti potrebbero essere in grado di scrivere il proprio codice che controllano. Il download del codice SCRAM su HTTP darebbe a un utente malintenzionato l'opportunità di modificare il codice SCRAM per inviare la password in chiaro o altrimenti esporlo.

    
risposta data 09.11.2018 - 19:01
fonte
7

In questo caso dovresti distribuire definitivamente TLS.

Se decidi di provare a inventare un sistema di sicurezza del trasporto su HTTP, alla fine finirai per implementare un susbset della funzionalità TLS. Ci sono molte insidie da prendere in considerazione quando si progetta e si implementa un tale sistema, che vengono ulteriormente amplificati quando si sceglie di provare ad 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 l'intera cosa si interrompe se qualcuno ha degli script disabilitati ( ad esempio con NoScript).

Come regola generale, è necessario scegliere l'implementazione costituita dai componenti più semplici, comprensibili e attendibili che richiedono la scrittura della quantità minima di codice critico per la sicurezza. Per citare Andrew Tannenbaum:

A substantial number of the problems (in application security) are caused by buggy software, which occurs because vendors keep adding more and more features to their programs, which inevitably means more code and thus more bugs.

    
risposta data 09.11.2018 - 19:31
fonte
6

Do I need to implement some encryption algorithm like RSA public key encryption?

Se stai pensando di provarlo, potresti anche andare al massimo e utilizzare HTTPS. Dal momento che non sembra essere un esperto, la crittografia "rolling your own" avrà indubbiamente delle errate implementazioni che lo rendono insicuro.

    
risposta data 09.11.2018 - 17:03
fonte
2

C'è in realtà un modo per autenticare un utente tramite una connessione non protetta: protocollo Secure Remote Password (SRP) . SRP è specificamente progettato per consentire a un client di autenticarsi su un server senza che un utente malintenzionato di Man-in-the-Middle sia in grado di acquisire la password del client o persino rieseguire l'autenticazione per impersonare successivamente il client, indipendentemente dal fatto che l'autenticazione sia riuscita o meno. Inoltre, l'autenticazione di successo 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 un certo numero di limitazioni di SRP:

  1. L'utente deve essersi registrato in modo sicuro, in quanto il processo di registrazione richiede la trasmissione di materiale equivalente alla password (anche se il server non ha bisogno di memorizzarlo).
  2. Anche se è sicuro tentare un accesso SRP con un server non attendibile (cioè, non esporterà la tua password a quel server, e sarai in grado di dire che il server non aveva la tua password nella sua database), non è sicuro caricare una pagina web di accesso da un server non affidabile (potrebbe mandare giù una pagina che cattura ogni tuo tasto e lo invia da qualche parte).
  3. Sebbene l'autenticazione di successo 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 quel codice per rubare la chiave simmetrica e fare modifiche alle richieste e alle risposte.

In altre parole, mentre SRP può essere utile in situazioni in cui si ha un client fidato che non ha bisogno di scaricare il codice tramite la connessione non protetta e si dispone anche di un altro modo sicuro per registrare l'utente (s), 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 utente malintenzionato, ad esempio qualcuno che spoofing DNS) può immettere codice dannoso nell'app Web e non c'è nulla che tu, la vittima, può fare al riguardo. Una volta che il codice è lì, può acquisire qualsiasi password o altri dati inseriti, rubare qualsiasi chiave generata e manomettere eventuali richieste inviate o risposte che ricevi senza che tu nemmeno lo sappia.

    
risposta data 10.11.2018 - 11:42
fonte
2

In realtà è abbastanza possibile.

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

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

  1. Il client inizia richiedendo un nonce al server, il server restituisce la chiave e il Nonce ;
  2. Il 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 dal replay.

L'interesse principale che vedo non è una protezione contro l'intercettazione, ma per essere completamente sicuro che la password in chiaro non sarà memorizzata sul server, nemmeno nel log di sistema (vedi Twitter o GitHub ).

Nota: HMAC può essere sostituito da PBKDF2.

    
risposta data 10.11.2018 - 10:38
fonte
1

È certamente possibile inviare una password in modo sicuro usando HTTP. C'è persino uno standard per questo. Si chiama HTTP-Digest ed è definito in RFC 7616. Fa parte delle specifiche HTTP da un po 'di tempo. È stato originariamente 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 la cosa più eclatante è che il server ha bisogno di avere la password in chiaro . Pertanto, mentre è possibile comunicare le password in modo sicuro utilizzando HTTP, non è possibile memorizzare in modo sicuro le password sul server durante l'utilizzo. Quindi, in pratica, non è utile.

Come altri hanno già detto, sarebbe meglio implementare TLS perché risolve più problemi tutti allo stesso tempo, ed è abbastanza avanti-compatibile.

    
risposta data 10.11.2018 - 23:51
fonte
1

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

Ma se è necessario utilizzare HTTP e qualsiasi server da implementare, è questo per uso programmatico o per uso umano? Se per uso umano, stai osservando l'autenticazione di base o basata su moduli? E i tuoi usi sono in grado di applicare un po 'di logica. non per joe pubblico da usare. È necessario proteggere qualcos'altro o semplicemente la password stessa?

Se è così potresti essere in grado di guardare:

  • Utilizza un pad / generatore di password monouso (gli RSA fob non sono economici, e se hai quel tipo di denaro da spendere allora puoi permetterti il TLS)
  • Altri tipi di autenticazione a 2 fattori come SMS (non senza i propri problemi).
  • Un semplice meccanismo di sfida / risposta per offuscare la password, ad esempio la pagina mostra due numeri su di esso nel testo (non etichettati in modo evidente), l'utente deve iniziare la password con un semplice calcolo come la differenza tra i due numeri aggiunti a ogni cifra di un PIN, magari con elementi casuali prima e / o e dopo, ad esempio 98634572dkkgdld. Cambiare i numeri di sfida dovrebbe interrompere gli attacchi di ripetizione che non vengono provati istantaneamente, ma se un utente malintenzionato riesce a catturare un numero sufficiente di tentativi può essere in grado di risolverlo. Non puoi inserire alcuna logica di offuscamento nello script rivolto all'utente che 'cos che sarà visto e se lo schema è troppo complesso i tuoi utenti ti odieranno ancora di più.

Lo farei comunque con TLS, ma i certificati sono economici (anche gratuiti) in questi giorni, così i complicati schemi di offuscamento non hanno più motivo di esistere.

    
risposta data 12.11.2018 - 22:55
fonte
-4

È necessario che il destinatario ti invii la sua chiave. Non puoi inviare a caso a qualcuno informazioni crittografate senza che prima tu ti fornisca la loro chiave pubblica personale.

    
risposta data 11.11.2018 - 02:58
fonte

Leggi altre domande sui tag