Come dividere login e logica di gioco durante la scrittura di server?


9

Sto costruendo un poker come server di gioco, avrei avuto tutti gli accessi e le logiche di gioco da gestire su un server, ma dalle mie ricerche sul web, ho appreso che questo non si ridimensionerebbe e avrebbe senso dividere il lavoro in un login e server di gioco. Ma quello che non ottengo è dopo aver gestito l'autenticazione nel server di accesso e dopo che il client ha effettuato una nuova connessione al server di gioco, come faccio a sapere quale client è quale? Non dovrei ripetere il login di nuovo e quindi vanificare lo scopo di avere un server per il login? C'è un modo per passare una connessione tra processi e macchine che non conosco? Scusa la mia poca conoscenza del networking.


4
YAGNI: non ne avrai bisogno. Non implementare un'ottimizzazione prematura. L'accesso suona come una parte molto banale del gioco, è improbabile che dividerlo sia vantaggioso; una volta che il tuo gioco ha abbastanza utenti che ti interessano (dovresti essere in grado di supportare migliaia di utenti su un singolo server, con altri solo per ridondanza), sarai in grado di assumere alcuni ingegneri del software che capiscono questo tipo di cose.
Mark

Hai accettato una risposta fuorviante, dovresti riconsiderarla attentamente o finirai con idee sbagliate nella tua testa e con un falso senso di sicurezza nel tuo codice.
o0 '.

Mi è piaciuta la risposta di Kylotan perché non devo avere una connessione extra tra i server di gioco e il server di accesso, posso anche vedere il punto di Philip che un compromesso della chiave segreta è un compromesso su tutti gli account che sono merci. Implementerò entrambe le versioni di accesso e chiederò a un esperto di sicurezza quando ricevo il controllo del mio codice. La mia domanda sembra piuttosto semplice e mi aspettavo che la loro sarebbe stata una soluzione standard su cui tutti erano d'accordo. Vai a capire. Se solo un esperto di sicurezza può venire in questa discussione e prendere una decisione.
user342580,

A rigor di termini, passare il token di accesso tra i server è più sicuro, a condizione che tu abbia un canale sicuro per farlo. È anche più difficile da implementare, il che aumenta il rischio di sbagliare. Un sistema di autenticazione dei messaggi basato su hash dovrebbe essere perfettamente sicuro a meno che qualcuno non riesca a ottenere la tua chiave segreta - e se possono ottenere la tua chiave tramite l'accesso ai tuoi sistemi interni, hai problemi che non verranno risolti inviando il login token manualmente.
Kylotan,

Risposte:


3

Sebbene la risposta di Philipp sia perfettamente valida, esiste un modo leggermente diverso che non richiede una connessione tra il server di accesso e il server di gioco, il che è utile se tale connessione è difficile.

  1. Quando l'utente si autentica correttamente sul server di accesso, viene inviato un indirizzo del server di gioco e un token di accesso come sopra. Tuttavia, questo token è composto da 2 parti: l'ora sul server di accesso e un hash di quel numero più il loro nome utente, il loro indirizzo IP, l'indirizzo IP o ID del server di gioco e una chiave segreta che solo tu conosci.
  2. Il client tenta di accedere al server di gioco fornito inviando questo token. Il server forma lo stesso hash di prima, in base alle informazioni nel token di accesso più il proprio indirizzo IP / ID e la chiave segreta. Se questo hash corrisponde a quello nel token, sai che il giocatore è autenticato correttamente. Quindi controllare che la data non sia troppo vecchia (ad es. Più di 1 minuto).

Questo funziona perché:

  • Non può essere copiato e riutilizzato poiché la data scadrà.
  • Non può essere costruito senza un nuovo login senza conoscere la chiave segreta.
  • Non può essere facilmente intercettato da qualcun altro (ad es. Con uno sniffer di pacchetti) e utilizzato perché l'indirizzo IP originale viene utilizzato per costruirlo.
  • Non può essere utilizzato per un altro account in quanto il nome utente fa parte dell'hash.
  • Non può essere utilizzato per accessi simultanei su diversi server di gioco poiché l'ID / indirizzo IP del server fa parte dell'hash.

O per dirla più semplicemente, l'hash assicura che è quasi impossibile per il mittente aver falsificato il proprio token di accesso e quindi le informazioni nel token possono essere attendibili.

Come con qualsiasi hash orientato alla sicurezza, usa la migliore funzione hash che puoi ottenere - al momento sembra che le persone apprezzino bcrypt, PBKDF2 e scrypt - e assicurati che la tua chiave segreta sia molto lunga in modo da rendere meno pratica la riproduzione della forza bruta.


Molto intelligente, preferisco di gran lunga questa soluzione. La mia domanda è quindi la chiave segreta. Dovrebbe essere come una passphrase o qualcosa del genere? E dovrebbe essere diverso per ogni utente?
user342580,

Questo non funziona o, in realtà, è una reimplementazione nascosta della risposta di @ Philipp. Fallisce perché presuppone che sia il server di accesso che il server di gioco conoscano la stessa chiave segreta. Se entrambi conoscono la chiave, una di loro deve contattare l'altra per fornirla. Oppure hai bisogno di una terza parte per inviarlo a entrambi. Ad ogni modo, è sniffabile come prima.
o0 '.

@Lohoris, l'idea è che possiedi sia il login che il server di gioco e puoi fornire loro la chiave segreta. Se non possedevi entrambi i server, in che modo il server di gioco poteva comunque fidarsi dell'autenticazione del server di accesso?
Kylotan,

@ user342580: vorrei usare una lunga frase di qualche tipo. Non deve differire per utente, ma se lo facesse, non farebbe male. Fintanto che la funzione di crittografia hash è abbastanza forte e la cambi periodicamente non dovrebbe importare.
Kylotan,

@Kylotan esattamente, e come fornisci loro la chiave? Perché consideri più sicura la connessione da te ai server, piuttosto che da un server all'altro?
o0 '.

8
  1. Dopo che l'utente si è autenticato nel loginserver, assegnagli un token (una stringa univoca, generata casualmente, troppo lunga per essere indovinata).

  2. Il loginserver sceglie un gameserver. Invia il token, il nome utente e tutti gli altri dati rilevanti sull'utente dal server di accesso al server selezionato.

  3. Invia il token e il nome host del gameserver al client. Quindi disconnettilo dal loginserver.

  4. Il client quindi si connette al gameserver con il suo nome utente e token.

  5. Quando il token del client corrisponde a quello appena segnalato dal loginserver, lo accetti.

Per garantire che ciò sia sicuro, i token devono essere creati da un generatore di numeri casuali crittograficamente sicuro, ogni token può essere accettato solo una volta dal server di gioco e i token inutilizzati devono essere eliminati dopo alcuni minuti.


Quindi sarebbe sufficiente usare bcrypt? Sto pensando di creare un token dall'hash del tempo + nome utente + password utilizzando bcrypt.
user342580,

Immagino che sarebbe. Si potrebbe indovinare un token quando si conosce la password, ma quando si conosce la password, è possibile accedere semplicemente nel modo normale.
Philipp,

1
bcrypt funziona fintanto che l'input è opportunamente casuale e non credibile. Se usi solo il tempo, l'attaccante può provare a prevedere il tempo, quindi eseguire bcrypt e ottenere il token. Assicurati di usare un sale segreto con il tempo o un randomizzatore sicuro (ad esempio / dev / random su sistemi UNIX / Linux).
Sean Middleditch,

La password potrebbe essere stata compromessa su un altro sito, quindi eviterei di supporre che sia un segreto adatto.
Sean Middleditch,

1
@SeanMiddleditch Quando la password è compromessa, la sicurezza viene comunque persa. Un utente malintenzionato che ha ottenuto la password non ha motivo di indovinare un token, perché potrebbe ottenerlo semplicemente accedendo in modo normale.
Philipp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.