Sta usando HMAC per trasmettere una password OK?

8

Sto scrivendo una piccola webapp e non voglio trasmettere le password di accesso come testo in chiaro. Dato che non ho SSL disponibile, ho scritto un sistema di una tantum che invia una stringa casuale con il modulo di login che viene poi utilizzato per cancellare la password usando HMAC-SHA256 sul lato client. Uso la stringa di verifica casuale come messaggio e la password dell'utente come chiave segreta per HMAC.

So che le soluzioni autoprodotte sono in genere una cattiva idea, quindi volevo chiedere se ho commesso un errore qui.

Modifica : sembra esserci un equivoco, non sto chiedendo informazioni sulla memorizzazione della password o sui sistemi di richiesta / risposta, ma sulla trasmissione di HMAC e password. Per chiarire un po ': la mia prima versione era HMAC(msg=password, key=challenge) , perché pensavo, beh, il messaggio che voglio trasmettere al server è la password dell'utente. Ma in seguito ho notato che la stringa della sfida non è esattamente una chiave segreta, quindi l'ho cambiata, ma questo mi ha fatto pensare che forse avrei fatto qualcosa di completamente sbagliato e ho pensato che avrei fatto meglio a chiederglielo.

    
posta Steffen 05.09.2011 - 10:03
fonte

4 risposte

11

Oltre ad essere uno schema auto-inventato, vedo almeno i seguenti problemi con la tua proposta:

  • Non ci sono vincoli con i dati reali. Quando si autentica un utente, non si desidera autenticare realmente "solo l'utente"; vuoi autenticare una sessione , ad esempio assicurati che ciò che seguirà sul link sarà garantito da quell'utente, e ciò che invierai sul link sarà visto solo dall'utente desiderato. Un attaccante attivo può dirottare la connessione e persino un intercettatore passivo può spiare ciò che manderai in seguito.

  • Lo schema è vulnerabile agli attacchi del dizionario offline. Le password sono deboli perché si adattano al cervello umano e il cervello umano non è troppo bravo a ricordare le password lunghe (e gli utenti umani non hanno la pazienza di digitare password lunghe). È una battaglia persa: i computer guadagnano regolarmente più potenza, ma non gli umani. Provare potenziali password tende ad essere un attacco di successo, e osservare il tuo schema produce abbastanza informazioni per provare le password (l'hacker deve solo calcolare un singolo HMAC per password indovinata, e vedere se corrisponde a ciò che è stato osservato). Tali attacchi possono essere in gran parte mitigati impiegando un processo di derivazione lenta (ad es. bcrypt ) ma un singolo HMAC semplicemente non essere abbastanza. È ancora una cattiva idea persino consentire un attacco di dizionario offline.

  • Il server dovrà memorizzare alcune informazioni sufficienti per l'autenticazione da parte di un utente. Ciò significa che un utente malintenzionato che ottiene l'accesso temporaneo in lettura alla memoria del server (ad esempio un dump del database tramite un'iniezione SQL) può ottenere password (o dati equivalenti a password) che gli consentono di impersonare gli utenti a un costo molto basso. I migliori schemi di password memorizzano sul server abbastanza dati per verificare una password, ma non di più.

Creare un supporto adeguato, sicuro e autenticato per il trasferimento dei dati non è un compito facile. Se hai davvero bisogno di reimplementare qualcosa da te invece di usare qualche libreria SSL / TLS, allora fai un favore e implementa un protocollo standard per questo, ad es. SSL / TLS . Se hai dei dubbi sul certificato, considera TLS con SRP (nessun certificato, autenticazione reciproca basata su password client-server, non vulnerabile agli attacchi del dizionario offline).

Modifica: sul tuo chiarimento nella tua modifica: utilizzando i dati segreti (la password) come chiave in HMAC e i dati pubblicamente noti (la sfida) come i dati in HMAC, è teoricamente molto meglio del contrario (l'HMAC è stato progettato affinché la chiave sia segreta); in pratica, data la struttura di HMAC, probabilmente non cambierebbe molto la sicurezza. Eppure i miei punti esposti sopra si applicano ancora.

    
risposta data 05.09.2011 - 21:13
fonte
6

Ci sono almeno due grandi svantaggi con il tuo schema di sfida / risposta:

  1. Devi memorizzare password in chiaro (o equivalenti in testo normale) sul lato server.

  2. Devi eseguire la gestione delle password sul lato client, il che significa che non esiste alcuna garanzia che il client stia eseguendo una parte di codice "valida" per gestire la password di cottura. Ad esempio, se javascript è stato utilizzato per gestire la "password di cottura", non si può essere certi che il client esegua un javascript dannoso, che (ad esempio) invia la password in testo semplice direttamente all'attaccante. Questo potrebbe accadere con XSS, o forse l'hacker è stato in grado di modificare il traffico HTTP prima che raggiunga il client.

Di conseguenza, potresti migliorare il tuo schema di sfida / risposta. Dai un'occhiata al link Questi algoritmi risolvono il "problema di memorizzazione di password in testo semplice".

Ma anche con questi "algoritmi di autenticazione sfida / risposta avanzati", rimane il secondo inconveniente. E non esiste un modo portatile / affidabile per gestirlo (eccetto "SSL"). Probabilmente le estensioni del browser potrebbero aiutare a ridurre alcuni problemi associati all'operazione "password cooking" basata su javascript (sul lato del cliend), ma non sarà valida come una connessione HTTPS sicura.

    
risposta data 05.09.2011 - 14:21
fonte
3

La domanda non specifica quale sia il modello di minaccia contro cui si sta difendendo, ma sospetto che lo schema che propone non sarà sufficiente nella pratica. La mia sensazione è che, in pratica, in qualsiasi modello di minaccia in cui le password in chiaro siano un problema, anche la proposta di risposta alle sfide non è adeguata.

In pratica, nella maggior parte delle situazioni in cui un utente malintenzionato può intercettare le comunicazioni, l'attaccante può anche manomettere le comunicazioni e lanciare un attacco man-in-the-middle. L'esempio più importante di questo è comunicare su una rete wireless aperta, ma altri includono spoofing DNS, malware lato client, proxy HTTP maligni, ecc. E se l'attaccante può montare un attacco man-in-the-middle, allora la sfida la proposta di risposta non è sicura: l'autore dell'attacco può iniettare Javascript dannoso che ruba la password o fa altre cose cattive.

Pertanto, ritengo che la proposta di risposta alle sfide fornisca un falso senso di sicurezza, perché non autentica il contenuto e il codice servito dal server. Sospetto che, invece di distribuire la tua soluzione, dovresti utilizzare SSL / TLS (ad es., HTTPS): se hai bisogno che le password trasmesse in chiaro siano problematiche, probabilmente hai bisogno di SSL / TLS.

    
risposta data 05.09.2011 - 20:28
fonte
1

Per autenticare un cliente, il tuo approccio sembra quasi corretto. Tuttavia, richiede la memorizzazione della password in chiaro sul server. Un piccolo aggiustamento è quello di memorizzare qualcosa derivato dalla password al posto della password stessa. Poi, dal lato client, ottieni le stesse informazioni da inserire in HMAC.

Fai molta attenzione, questa è l'autenticazione reciproca NOT ! Il client non autentica il tuo sito web e potrebbe essere ingannato / falsificato nel fornire la sua password.

E hai pensato di ripetere l'attacco?

Che ne dici di un attacco di forza bruta off-line?

Quello che sto facendo è porre una strong enfasi sulla prima parte della tua ultima frase.

    
risposta data 05.09.2011 - 14:49
fonte

Leggi altre domande sui tag