Sto progettando un gioco multiplayer online e sto cercando un buon compromesso tra comunicazioni sicure con utilizzo minimo di CPU e larghezza di banda. La mia soluzione ideale userebbe solo i pacchetti UDP dal momento che TCP è una scelta sbagliata per i requisiti in tempo reale del gioco. Tuttavia, non ho problemi a tornare su TCP per il server di login.
Ecco la mia idea.
Quando gli utenti accedono per la prima volta al servizio :
- Gli utenti si connettono a un server di autenticazione (che contiene una certificazione di Verisign) tramite SSL.
- Il server di autenticazione convalida le credenziali di accesso dell'utente.
- Se il login è valido, due coppie di chiavi pubbliche / private AES a 256 bit vengono generate dal server. All'utente viene inviata una chiave privata e una chiave pubblica da ricordare, che possono essere successivamente utilizzate per la comunicazione simmetrica. Il server memorizza le coppie di chiavi opposte.
- Inoltre, viene generato un numero intero a 32 bit casuale che viene inviato all'utente. Per ora chiamerò questa "chiave di offuscamento".
- La connessione SSL è terminata. Da qui in avanti, tutti i dati vengono inviati tramite UDP.
Ogni volta che un utente deve eseguire una transazione sicura con un server :
- Per le richieste, il carico utile viene crittografato utilizzando la chiave pubblica ricevuta dal cliente.
- Per le risposte, il carico utile viene decifrato utilizzando la chiave privata ricevuta dal cliente.
La mia prima domanda - è sicura e consigliabile ?
L'altro problema che sto cercando di risolvere è l'invio di pacchetti tempestivi per gli aggiornamenti che non devono essere altrettanto sicuri ma estremamente frequenti, come il movimento e la posizione dei giocatori.
L'invio dei dati in chiaro è pericoloso a causa di una ripetizione di pacchetti banale e attacchi man-in-the-middle. Tuttavia, ritengo che l'esecuzione della crittografia AES per ogni pacchetto di questo tipo sia troppo impegnativa per la CPU. Invece, sto considerando una semplice confusione di cifratura XOR come segue:
- Crea una chiave per la cifratura XOR con XOR - un timestamp a 32 bit con la "chiave di offuscamento" ricevuta in precedenza.
- Applica il codice XOR al payload del pacchetto UDP.
- Invia il pacchetto UDP con il timestamp nell'intestazione più il carico utile offuscato. In questo modo il server può de-offuscare usando lo stesso timestamp.
Una cosa che spero di ottenere con questo è semplicemente scoraggiare gli sniffer di pacchetti e gli "script kiddies" che potrebbero provare banalmente a decodificare il protocollo. Un'altra preoccupazione è la prevenzione degli attacchi di replay dei pacchetti, che è la ragione per includere il timestamp nella cifratura XOR. Infine, spero che l'aggiunta della "chiave di offuscamento" nel mix prevenga attacchi banali di man-in-the-middle.
La mia seconda domanda - c'è un modo più semplice e / o più efficace per raggiungere questi obiettivi ?
Mi rendo conto che si tratta di domande caricate, quindi grazie in anticipo per aver dedicato del tempo a leggere questo.