Questo schema di autenticazione è sicuro?

0

Voglio autenticare un client di una pagina web e assicurarmi che sia un particolare utente.

Diciamo che abbiamo già concordato un hash particolare ( SHA256 , in realtà, che ritengo sia abbastanza sicuro per questo) e che entrambi abbiamo già scambiato un key in un file tramite un mezzo attendibile.

Questo key è praticamente un file di testo con 2K di lettere casuali. Lo ho memorizzato nel mio server, lo hanno memorizzato da qualche parte nel loro computer.

Questi sono i passi studiati per autenticare il client:

  1. Il server genera un challenge , una stringa casuale di 128 lettere.
  2. Il server invia challenge al browser del client.
  3. Il client ha accesso a un campo di input dove caricano il loro file key .
  4. Il client calcola un answer aggiungendo key al loro contenuto challenge e calcolando il suo hash.
  5. Il client restituisce solo answer per questo particolare challenge .
  6. Il server confronta il answer ricevuto con uno generato localmente e, se corrispondono, posso supporre che il client sia la persona che penso che sia.

Assunzione finale, lo scambio di challenge e answer attraverso il web può avvenire attraverso un canale non sicuro. In realtà, supponiamo che accadrà attraverso un canale non sicuro, cioè HTTP.

Questo schema è sicuro?

In caso negativo, quali sono le sue insidie?

Nel passaggio 4, fa la differenza se computo l'hash come challenge + key invece di key + challenge . Immagino che questo abbia a che fare con l'algoritmo di hash che ho scelto, e penso che lo SHA256 gestisca bene quelle cose, ma non sono esperto.

Importa molto se aumento / diminuisci la lunghezza di key e challenge ?

    
posta almosnow 01.03.2016 - 15:42
fonte

5 risposte

62

Nessuna crittografia che utilizza JavaScript sul lato client può essere protetta senza HTTPS. Qualsiasi malintenzionato MITM può inviare JavaScript che può fare qualsiasi cosa con i segreti a cui il browser ha accesso, quindi non ci sarà alcun segreto.

Se non è assolutamente possibile utilizzare HTTPS, l'utente deve disporre di uno strumento per calcolare la risposta all'esterno del browser e incollare il risultato nel browser. Anche così, tutti i dati trasmessi dopo l'autenticazione sono ancora soggetti a intercettazione e modifica, il che rende l'autenticazione piuttosto inutile dal punto di vista della protezione degli utenti.

Leggi:

Cosa c'è di sbagliato nella crittografia nel browser? - Tony Arcieri oppure Crittografia Javascript considerata dannosa - NCC Gruppo oppure i 1.030.000 risultati restituiti per la ricerca "errato con la crittografia javascript" su Google

Modifica:

BTW, anche se si utilizza un programma esterno per gestire l'autenticazione e forse anche la crittografia dei dati che vanno su HTTP, si può ancora avere una sicurezza ridotta rispetto all'utilizzo di HTTPS. Il miglior esempio è la cifratura SEED coreana che espone gli utenti bloccando gli utenti e addestrandoli a fidarsi dei controlli ActiveX e di IE. Vedi questo articolo del blog ).

    
risposta data 01.03.2016 - 16:07
fonte
19

Se hai un attacco in stile MitM, è inutile: un utente malintenzionato seduto tra il tuo client e il tuo server può inoltrare la sfida al client, attendere che lo completi, quindi inviarlo di nuovo al server, mentre invia un messaggio di rifiuto al client (e, dato che gli stai facendo incollare nella chiave, possono anche rubarlo - se l'area "input chiave" fa parte del modulo di invio, verrà inclusa nella richiesta POST effettuata dal client al server Questo dipende dall'implementazione specifica, ma è un errore abbastanza comune da fare).

Allo stesso modo, se il tuo codice client può essere modificato in qualsiasi modo (può: stai usando HTTP), sarebbe banale aggiungere codice per inviare la chiave a terzi, per un uso successivo. Questo non sarebbe ovvio per l'utente finale.

Se il tuo server viene compromesso in qualsiasi momento, tutti i tuoi file chiave diventano inutili: non puoi sapere se il proprietario originale o l'autore dell'attacco sta tentando di connettersi.

L'autenticazione client HTTPS tenta di evitare questi problemi. In primo luogo, è difficile collegare la connessione MIM, poiché è crittografata con una chiave del server: è necessario compromettere il server per poterlo utilizzare con MitM (senza un difetto di implementazione). In secondo luogo, il server memorizza le chiavi pubbliche per i client. Anche se sono stati rubati, puoi ancora usarli per verificare i client, dal momento che non puoi rigenerare le chiavi private del client da loro. Sono pubblici. Non importa chi li ha. Infine, è ben collaudato ed è stato trovato abbastanza sicuro nel tempo. Questo è un punto chiave quando si utilizza qualsiasi forma di sicurezza - è il modo in cui i metodi sono sicuri o meno.

Usa semplicemente HTTPS - sì, potrebbe essere difficile da implementare, ma è progettato per questo!

    
risposta data 01.03.2016 - 16:14
fonte
18

Insecure è insicuro. Se lo scambio passa su un HTTP non protetto o qualcosa di simile, un attaccante attivo può semplicemente osservare lo scambio iniziale, lasciare che il client esegua il passo di autenticazione e dirottare la connessione da quel punto, sostituendo le richieste del client con le proprie. Man-in-the-Middle , per definizione, agisce subito, non registrando elementi e riutilizzandoli più tardi.

In parole concettuali, con il tuo metodo di autenticazione, puoi in qualche modo accertarti che il cliente previsto sia coinvolto in qualche punto, ma questo non si estende ai dati dell'applicazione che ricevi. data non è autenticato.

Se vuoi correggerlo, devi coprire ogni elemento di dati inviato dal client con un metodo di autenticazione che il server può verificare, ad es. un MAC . Questo complicherà il tuo protocollo, e a quel punto faresti meglio a cedere all'inevitabile e usare SSL / TLS, perché è proprio quello di cui hai bisogno.

(Una domanda aperta è come utilizzare un protocollo orientato al flusso come SSL / TLS su un mezzo di trasporto che non è uno stream, tipico di situazioni in cui è possibile utilizzare solo HTTP semplice e il proxy HTTP non è disposto a supportare il metodo CONNECT . Il meglio che può essere offerto in questo momento è DTLS , dove i datagrammi possono essere concettualmente trasmessi come richieste HTTP e risposte, ma richiederebbe una rigida disciplina affinché il client e il server sappiano sempre di chi è il turno di parlare e si sentono decisamente goffi.)

A parte questo problema fondamentale con lo scopo dell'autenticazione, alcune osservazioni extra:

  • I file chiave dell'utente, come memorizzati sul server, sono un obiettivo succoso per gli aggressori. Un nastro di backup perso o un attacco di SQL injection può consentire all'utente malintenzionato di leggere questi file, a quel punto può impersonare gli utenti a proprio piacimento. Questo è considerato negativo quando i "file chiave" sono in realtà password utente; parliamo di "password in chiaro".

  • I file chiave non sono necessariamente segreti molto . Se l'utente produce personalmente il proprio file chiave, un numero deprimente di utenti utilizzerà semplicemente un'immagine che è stata scaricata da Internet. L'autore dell'attacco può scaricare lo stesso file ...

  • Se il codice client è in Javascript, appena ottenuto dal server Web, allora è necessario comunque HTTPS, perché altrimenti l'autore dell'attacco potrebbe semplicemente modificarlo quando il browser dell'utente lo scarica.

risposta data 01.03.2016 - 16:11
fonte
8

Perché chiedere se è sicuro in primo luogo se hai intenzione di abbattere qualcuno che ti dice come proteggerlo?

HTTPS non richiede al client di fare nulla. Ti stai comportando come se avessero bisogno di installare qualche software speciale o qualcosa del genere, ma il browser gestisce tutto questo per te. Se hai appena implementato il lato server HTTPS, l'intera operazione diventa sicura e non hai bisogno del tuo sistema di autenticazione personalizzato (che potrebbe avere buchi di sicurezza nell'implementazione / codice effettivi).

In realtà, non avrai più sicurezza rispetto all'utilizzo di HTTPS. Qualsiasi altra soluzione è solo più complessa da fare e probabilmente non altrettanto sicura.

    
risposta data 02.03.2016 - 10:51
fonte
4

Quello che stai facendo è una sorta di autenticazione a mezzo messaggio, ma un po 'al contrario.

Normalmente con autenticazione dei messaggi un client creerà un messaggio e firma il messaggio con una chiave . Il messaggio e la firma vengono inviati al server. Il server ha anche la chiave in modo che possa ricreare la firma stessa e confrontarla con quella inviata dal client. Se corrispondono, il messaggio deve essere autentico e non può essere stato manomesso. Questo può essere usato per verificare l'identità ma non offre alcuna privacy (chiunque può leggere il messaggio).

L'identità è dimostrata perché gli attacchi MITM non possono generare / falsificare la firma corretta senza la chiave. Potrebbe essere possibile per un MITM utilizzare un Attacco di ripetizione , ma questo può essere prevenuto usando un crittografico Nonce nel messaggio.

In relazione al tuo problema, puoi far firmare al client ogni richiesta fatta al server (cioè generare un MAC e inviarlo al server come parte della richiesta) per provare l'identità. Il server non ha bisogno di inviare alcun tipo di sfida.

    
risposta data 02.03.2016 - 14:53
fonte

Leggi altre domande sui tag