Qual è il modo migliore per autenticare un utente utilizzando una websocket?

5

Sto creando un gioco multiplayer (basato su websockets) che viene eseguito direttamente dal browser e che ha funzionalità multiplayer. Ogni giocatore deve avere il proprio account (Username e password). Quando stavo pianificando il gioco, mi sono reso conto che il modo più semplice per migrarlo su altre piattaforme è scrivere in HTML5. Quindi, ho bisogno di creare un sistema di login usando JS e websockets. Ma non sono sicuro di quanto sia sicuro inviare un messaggio con un contenuto come username e password al server websocket (che viene eseguito in una macchina virtuale Java).

    
posta zearthur99 18.11.2014 - 00:12
fonte

2 risposte

7

Se vuoi sicurezza, trasmettere i dati di autenticazione tramite TLS è un grande inizio. Ma supponiamo che il websocket sia già configurato su TLS. Una soluzione che raccomanderei sarebbe basata su un meccanismo di risposta alle sfide:

  1. Il server imposta una serie casuale di byte (la sfida), imposta un timeout al termine del quale la sfida non sarebbe autorizzata.
  2. Il client invierà "testo semplice" il nome utente e la sfida e un hash (con un algoritmo SHA2 o SHA3) di challenge || username || f(password) , f(password) è come la password è memorizzata nel database (un SHA256 di password per esempio).
  3. Il server verifica i dati del nome utente e sfida la risposta e, in caso affermativo, autentica l'utente. Inoltre, invalida la sfida di invalidare qualsiasi tentativo futuro utilizzando questa sfida.

Questo metodo fornisce una funzionalità anti-replay: un utente malintenzionato non può acquisire i dati e riprodurli in seguito per l'autenticazione.

Tuttavia, ho un grosso problema con questo metodo: f(password) ha qui la stessa sicurezza di password : se il database perde, qualsiasi utente malintenzionato potrebbe autenticarsi come chiunque altro. Dico "all'incirca" perché, se conservato in chiaro, dal momento che molti utenti usano la stessa password su più siti web (che è male), i loro account potrebbero essere compromessi altrove.

Non riesco a pensare a un metodo di protezione contro una fuga di database e un meccanismo anti-replay, ma un meccanismo anti-database (invia password utente in chiaro su TLS, password hash con database salt e confronta con database) over TLS dovrebbe essere sufficiente contro la maggior parte dei rischi che incontrerai

    
risposta data 18.11.2014 - 00:35
fonte
2

Se si desidera una password, il modo migliore è utilizzare TLS e quindi inviare le password in chiaro. Questo è più semplice di un meccanismo di risposta alle sfide.

Se tuttavia non puoi avere TLS per i websocket, ma hai TLS per il codice (fornito tramite HTTP), la cosa migliore da fare è effettuare il login tramite HTTPS, generare cookie di sessione (o qualche altra forma di chiavi) e usarli per autenticare il websocket. Se si effettua la challenge-response in chiaro, un utente malintenzionato può forzare la password usando questa comunicazione. Con l'approccio di sessione, un utente malintenzionato può solo catturare la sessione del tuo gioco (non sensibile), ma non la (eventualmente riutilizzata) password. Tuttavia, quando hai TLS su nessuno dei due, dovresti consentire agli utenti di autenticarsi tramite terze parti, ad es. attraverso OpenID. Quindi non è necessario gestire dati sensibili come le password. OpenID è una buona opzione anche per gli altri casi.

    
risposta data 18.11.2014 - 02:53
fonte

Leggi altre domande sui tag