Fondamentalmente, hai tre requisiti:
- non dovrebbe essere facile usare la stessa chiave per più istanze client,
- non dovrebbe essere facile generare nuove chiavi valide e
- non dovrebbe essere facile rubare la chiave di un cliente legittimo.
La prima parte dovrebbe essere piuttosto semplice: non lasciare che due giocatori accedano allo stesso server con la stessa chiave contemporaneamente. Puoi anche fare in modo che i server scambino informazioni sugli utenti che hanno effettuato l'accesso o contattare un server di autenticazione condiviso, in modo che anche l'utilizzo della stessa chiave per giocatori diversi su server diversi allo stesso tempo fallisca. Probabilmente vorrai anche cercare modelli sospetti di utilizzo delle chiavi e, se determini che una chiave è trapelata, aggiungila a un elenco di chiavi vietate.
Per la seconda parte, un modo è semplicemente quello di mantenere un database di tutte le chiavi emesse valide. Finché le chiavi sono abbastanza lunghe (diciamo, 128 bit o più) e scelte casualmente (usando un RNG sicuro), le probabilità che chiunque riesca a indovinare una chiave valida sono essenzialmente zero. (Anche chiavi molto più brevi possono essere sicure se si utilizza un qualche tipo di limitazione della velocità in caso di tentativi di accesso falliti per fermare i tentativi di trovare chiavi valide con la forza bruta.)
In alternativa, puoi generare le chiavi prendendo qualsiasi identificatore univoco e aggiungendo ad esso un codice di autenticazione del messaggio (come HMAC ), calcolato usando una chiave master segreta. Ancora una volta, fintanto che il MAC è abbastanza lungo, le probabilità che chiunque non sappia che la chiave master sia in grado di indovinare un MAC valido per qualsiasi ID è trascurabile. Un vantaggio di questo metodo, oltre a rimuovere la necessità di un database di chiavi, è che l'identificatore può essere qualsiasi stringa univoca e può codificare le informazioni sul client per cui è stata emessa la chiave.
Un problema con l'utilizzo dei MAC è che i server di gioco ufficiali (o almeno il server di autenticazione) devono conoscere la chiave master per verificare il MAC, il che significa che, se i server vengono hackerati, la chiave master potrebbe essere trapelata. Un modo per mitigare questo rischio potrebbe essere quello di calcolare diversi MAC per ciascun ID, utilizzando chiavi master diverse, ma memorizzando solo una delle chiavi master sui server di gioco. In questo modo, se la chiave master viene mai trapelata e utilizzata per generare ID falsi, è possibile revocarla e passare a un'altra chiave master. In alternativa, è possibile sostituire i MAC con firme digitali , che possono essere verificati utilizzando solo la metà pubblica della chiave principale.
Per la terza parte, un approccio consiste nell'assicurarsi che il client non invierà la propria chiave a nessuno senza verificare che il destinatario sia davvero un server ufficiale legittimo. Ad esempio, potresti utilizzare SSL / TLS (o DTLS ) per il processo di accesso, emettere certificati personalizzati per i tuoi server di gioco e avere solo i certificati di attendibilità del client emessi da te. Convenientemente, l'utilizzo di TLS proteggerà anche le chiavi del client (e qualsiasi altro dato di autenticazione) da intercettatori, ad esempio su reti WLAN pubbliche.
Sfortunatamente, questo approccio non consente ai server di terze parti di verificare le chiavi del client anche se lo desiderano. È possibile aggirare il problema configurando un server di autenticazione ufficiale che i server di gioco di terze parti possono utilizzare, ad esempio facendo in modo che il client acceda al server di autenticazione e riceva un token casuale una tantum che possono utilizzare per accedere al server di gioco (che quindi invia il token al server di autenticazione per verificarlo).
In alternativa, è possibile emettere certificati client effettivi o qualcosa di simile ai propri clienti. È possibile utilizzare un protocollo esistente (come TLS) che supporti l'autenticazione del certificato client (consigliato) o implementare il proprio, ad esempio in questo modo:
- Il certificato client è costituito da una stringa di ID arbitraria, una coppia di chiavi pubblica / privata e una firma digitale dell'ID e della chiave pubblica che utilizza la chiave master.
- Per accedere, il client invia il proprio ID, chiave pubblica e firma. Il server risponde con una stringa di verifica univoca (preferibilmente includendo un ID server e un timestamp, che il client dovrebbe verificare), che il client firma con la chiave privata (per dimostrare di conoscere la chiave) e invia la firma al server.
- Il server controlla entrambe le firme, dimostrando che l'ID + chiave pubblica forma una chiave client legittima (poiché erano firmate con la chiave master) e che la chiave client appartiene effettivamente al client (poiché il client potrebbe firmare la sfida del server con il privato chiave).
(Questo protocollo potrebbe essere ulteriormente semplificato facendo in modo che il client generi la "sfida", consistente in un ID server e un timestamp, e firmarlo. Naturalmente, il server deve verificare che l'ID e il timestamp siano validi. Si noti inoltre che questo semplice protocollo, da solo, non impedirà a un aggressore intermediario di essere in grado di dirottare la sessione del client, sebbene impedirà loro di ottenere la chiave privata del client necessaria per gli accessi futuri.)