Fondamentalement, vous avez trois exigences:
- il ne devrait pas être facile d'utiliser la même clé pour plusieurs instances client,
- il ne devrait pas être facile de générer de nouvelles clés valides, et
- il ne devrait pas être facile de voler la clé d'un client légitime.
La première partie devrait être assez simple: ne laissez pas deux joueurs se connecter au même serveur avec la même clé en même temps. Vous pouvez également demander aux serveurs d'échanger des informations sur les utilisateurs connectés ou de contacter un serveur d'authentification partagé, de sorte que même l'utilisation de la même clé pour différents joueurs sur différents serveurs en même temps échouera. Vous souhaiterez probablement également rechercher des modèles suspects d'utilisation des clés et, si vous déterminez qu'une clé a été divulguée, ajoutez-la à une liste de clés interdites.
Pour la deuxième partie, une façon consiste simplement à maintenir une base de données de toutes les clés émises valides. Tant que les clés sont suffisamment longues (disons, 128 bits ou plus) et choisies au hasard (en utilisant un RNG sécurisé), les chances de quiconque parvient à deviner une clé valide sont essentiellement nulles. (Même des clés beaucoup plus courtes peuvent être sûres si vous utilisez une sorte de limitation de débit sur les tentatives de connexion infructueuses pour arrêter les tentatives de recherche de clés valides par force brute.)
Alternativement, vous pouvez générer des clés en prenant n'importe quel identifiant unique et en y ajoutant un code d'authentification de message (tel que HMAC ), calculé à l'aide d'une clé principale secrète. Encore une fois, tant que le MAC est suffisamment long, les chances pour quiconque ne connaît pas la clé principale de deviner un MAC valide pour n'importe quel ID est négligeable. Un avantage de cette méthode, en plus de supprimer le besoin d'une base de données de clés, est que l'identifiant peut être n'importe quelle chaîne unique et peut coder des informations sur le client pour lequel la clé a été émise.
Un problème avec l'utilisation des MAC est que les serveurs de jeu officiels (ou au moins le serveur d'authentification) doivent connaître la clé principale afin de vérifier le MAC, ce qui signifie que si les serveurs sont piratés, la clé principale peut être divulguée. Une façon d'atténuer ce risque pourrait être de calculer plusieurs MAC pour chaque ID, en utilisant des clés principales différentes, mais de stocker uniquement l'une des clés principales sur les serveurs de jeu. De cette façon, si cette clé principale est jamais divulguée et utilisée pour générer de faux identifiants, vous pouvez la révoquer et passer à une autre clé principale. Alternativement, vous pouvez remplacer les MAC par des signatures numériques , qui peuvent être vérifiées en utilisant uniquement la moitié publique de la clé principale.
Pour la troisième partie, une approche consiste à s'assurer que le client n'enverra sa clé à personne sans vérifier que le destinataire est vraiment un serveur officiel légitime. Par exemple, vous pouvez utiliser SSL / TLS (ou DTLS ) pour le processus de connexion, émettre des certificats personnalisés pour vos serveurs de jeu et ne faire émettre que les certificats de confiance client. De manière pratique, l'utilisation de TLS protégera également les clés client (et toutes les autres données d'authentification) des écoutes indiscrètes, par exemple sur les WLAN publics.
Malheureusement, cette approche ne permet pas aux serveurs tiers de vérifier les clés client même s'ils le souhaitent. Vous pouvez contourner ce problème en configurant un serveur d'authentification officiel que les serveurs de jeux tiers peuvent utiliser, par exemple en demandant au client de se connecter au serveur d'authentification et de recevoir un jeton unique aléatoire qu'ils peuvent utiliser pour se connecter au serveur de jeu (qui soumet ensuite le jeton au serveur d'authentification pour le vérifier).
Alternativement, vous pouvez émettre des certificats clients réels, ou quelque chose comme eux, à vos clients. Vous pouvez soit utiliser un protocole existant (comme TLS) qui prend en charge l'authentification par certificat client (recommandé) ou implémenter le vôtre, par exemple comme ceci:
- Le certificat client se compose d'une chaîne d'ID arbitraire, d'une paire de clés publique / privée et d'une signature numérique de l'ID et de la clé publique à l'aide de la clé principale.
- Pour se connecter, le client envoie son identifiant, sa clé publique et sa signature. Le serveur répond avec une chaîne de défi unique (comprenant de préférence un ID de serveur et un horodatage, que le client doit vérifier), que le client signe avec la clé privée (pour prouver qu'il connaît la clé) et envoie la signature au serveur.
- Le serveur vérifie les deux signatures, prouvant que l'ID + la clé publique forment une clé client légitime (puisqu'elles ont été signées avec la clé principale) et que la clé client appartient réellement au client (puisque le client peut signer le défi du serveur avec le privé) clé).
(Ce protocole pourrait être encore simplifié en demandant au client de générer le "défi", consistant en un ID de serveur et un horodatage, et de le signer. Bien sûr, le serveur doit alors vérifier que l'ID et l'horodatage sont valides. Notez également que ce protocole simple, à lui seul, n'empêchera pas un attaquant intermédiaire de pouvoir détourner la session du client, bien qu'il l'empêchera d'obtenir la clé privée du client nécessaire pour les futures connexions.)