Comment les jeux multijoueurs doivent-ils gérer l'authentification?

27

J'ai cherché à comprendre comment un système d'authentification fonctionnerait dans les jeux, mais après de nombreuses recherches, il semble que travailler avec ssl / certificats pourrait être un peu compliqué pour un jeu multijoueur avec beaucoup moins de capacité qu'un MMO.

Je sais que les jeux multijoueurs réussis en ont besoin, mais je voudrais vérifier si d'autres jeux multijoueurs prennent généralement ces précautions.

EDIT : Je vais décrire ce que j'ai en tête. Le serveur gère non seulement la logique du jeu, mais aussi l'authentification. Donc, pour jouer sur un serveur spécifique (que tout le monde pourrait démarrer), vous devez d'abord créer un compte sur le serveur, et chaque fois que vous voulez y jouer, connectez-vous comme d'habitude (mot de passe / nom d'utilisateur).

Ma question est, est-ce que la fourniture d'un canal sécurisé pour se connecter / enregistrer un compte ne serait pas pardonnable / compréhensible dans ce contexte? Je suis également intéressé de savoir comment les jeux avec une architecture similaire géreraient cette question.

Wolfrevo Kcats
la source
Les certificats SSL sont compliqués et difficiles à gérer. Je vous recommande de rester loin.
ashes999
4
@ ashes999 En fait, la douleur vient de leur signature par les autorités de l'AC. Pour un jeu qui ne communique pas avec le serveur via un navigateur, vous pouvez utiliser un certificat éternel auto-signé, vous pouvez même demander aux clients de vérifier que le bon certificat est utilisé. Étant donné une bonne bibliothèque, il est assez facile à installer.
aaaaaaaaaaaa
Il existe des solutions d'hébergement d'applications qui vous offrent un SSL gratuit via des sous-domaines et leurs certificats génériques. Vous pouvez donc utiliser HTTPS sans même avoir à penser aux certificats SSL eux-mêmes. Tout comme une autre option.
Sean Middleditch
@eBusiness vous avez raison.
ashes999

Réponses:

41

En ce qui concerne spécifiquement le dernier bit de votre question: Non, il n'est jamais pardonnable d'avoir un système d'authentification non sécurisé. Les utilisateurs sont rarement éclairés en matière de sécurité informatique. Les utilisateurs utilisent le même mot de passe pour votre petit jeu que pour leur compte Google, leur compte Facebook, leur compte bancaire, etc. Même si vous pouvez prétendre que c'est leur faute pour avoir utilisé de mauvaises habitudes de sécurité sur Internet, c'est vous qui serez tenu responsable si votre jeu est utilisé comme vecteur d'attaque pour voler les informations de connexion des utilisateurs. En tant que développeur qui sait mieux, les seules options éthiques sont de sécuriser correctement votre processus d'authentification ou de ne pas en avoir du tout.

Comme certains conseils non sollicités mais liés, les utilisateurs ne veulent de toute façon pas être tenus de s'inscrire à votre jeu. Ils peuvent le faire s'ils veulent jouer assez mal à votre jeu, mais avoir une autre connexion Freaking pour vous inscrire va simplement chasser de nombreux joueurs potentiels. Les utilisateurs en ont assez de créer un nouveau compte pour chaque site, service et jeu, surtout s'ils ont besoin d'une validation par e-mail ou autre. Si vous le pouvez, évitez d'avoir une connexion ou utilisez un service d'authentification tiers existant avec lequel les utilisateurs ont probablement déjà un compte. Vous aurez plus de joueurs de cette façon. Cela va tripler si vous prévoyez d'avoir tout type d'achats intégrés.

Jeux Web

Une option populaire - en particulier pour les jeux Web, bien qu'elle fonctionne également pour les jeux traditionnels - consiste à utiliser un service d'authentification tiers basé sur le Web. Facebook et Google ont tous deux des API bien documentées (toutes deux basées sur des API standardisées, iirc) pour l'authentification. Ils nécessitent la possibilité d'ouvrir une fenêtre de navigateur et de diriger l'utilisateur vers leurs services, mais cela est assez facile à faire sur la plupart des plates-formes non console, et bien sûr trivial pour les jeux Web.

Ces services s'occupent de tous les détails désordonnés du cryptage du trafic de connexion sur le fil, du stockage sécurisé des informations de connexion et de la validation des connexions utilisateur. Votre serveur de jeu n'a alors qu'à implémenter la partie du protocole qui reçoit un cookie de l'utilisateur et demande au service d'authentification si le cookie est valide ou non, ce qui peut être fait avec un simple HTTP dans la plupart des cas.

Je ne prétendrai pas que la plupart des jeux multijoueurs traditionnels le font, car ils ne le font pas, mais je dirai que la plupart des jeux Web occasionnels en ligne le font.

Pour les jeux traditionnels (non Web), faciliter cette procédure de connexion est possible en incorporant un navigateur (Awesomium, Chromium Embedded Framework ou directement Webkit étant des choix populaires) ou en appelant à un navigateur externe (cela prend un peu plus de fanagling pour obtenir le cookie d'authentification cependant, et n'est pas vraiment plus facile que d'incorporer l'une des bibliothèques susmentionnées).

Un exemple typique de cette approche est tout jeu Facebook.

Jeux traditionnels utilisant HTTPS

Il est de plus en plus normal d'avoir un simple service HTTPS pour la connexion. De nombreux jeux utilisent des protocoles personnalisés, mais la plupart d'entre eux sont incomplets (ils ont une connexion sécurisée, mais aucun moyen sécurisé de créer / mettre à jour un compte, ils ont donc besoin du service HTTPS de toute façon) ou sont tout simplement horriblement insécurisés.

Vous n'avez même pas besoin d'obtenir un certificat SSL personnalisé. Il existe des fournisseurs d'hébergement d'applications en ligne qui vous fournissent un sous-domaine et utilisent un certificat SSL générique. Vous pouvez mettre votre service d'authentification sur mygame.someservice.com, qui est couvert par le certificat générique * .someservice.com que certains services maintiennent, et vous êtes prêt à partir.

L'idée ici est que l'utilisateur se connecte à votre service, ce qui génère un cookie de session unique, que l'utilisateur peut ensuite transmettre à votre serveur de jeu principal. Le serveur demande alors au système de connexion si le cookie est valide pour l'utilisateur demandé. Il y a généralement un délai très court sur le cookie, de l'ordre de quelques secondes (15-30, par exemple), et il est généralement invalidé une fois utilisé, ce qui rend les attaques par rejeu impossibles.

Notez que HTTPS est mon option la plus recommandée si vous prévoyez d'envoyer des informations de paiement par câble depuis l'intérieur du client lui-même. Cependant, il est nettement préférable d'utiliser un tiers pour cela. Si vous pensez que sécuriser quelque chose d'aussi simple qu'un mot de passe est trop de travail, vous ne voulez même pas penser à essayer de respecter les règles de conformité PCI minimales (et honnêtement assez inadéquates) pour le stockage et le traitement des numéros de carte de crédit. Vous aurez de toute façon une meilleure utilisation des ventes si vous avez des utilisateurs qui utilisent des services de paiement tiers de confiance avec lesquels ils sont déjà enregistrés.

Un avantage important de séparer votre service de connexion du serveur de jeu principal est qu'il permet de lier des fonctionnalités externes à des comptes d'utilisateurs indépendants du jeu. Vous pouvez avoir certaines fonctionnalités de compte (afficher des avatars ou autres) sur votre site Web, ou peut-être autoriser la liaison de comptes Facebook à vos comptes, ou peut-être que plusieurs jeux partagent une seule plate-forme de compte sous-jacente (par exemple, les fonctionnalités Galaxy at War de Mass Effect 3).

Un exemple de jeu populaire utilisant HTTPS pour l'authentification est Minecraft.

Authentification Web tierce avec les jeux clients natifs

Il est possible d'utiliser des services tiers comme Facebook Connect ou Google avec un client natif. Facebook, par exemple, possède un SDK natif pour iOS et Android, tout comme Google. Certains services ont également des SDK natifs pour les clients PC traditionnels.

Si le service cible ne dispose pas d'un SDK natif et nécessite l'utilisation d'un navigateur Web, vous pouvez simplement intégrer un navigateur dans votre jeu. Cependant, certains utilisateurs peuvent se méfier de l'utilisation d'un navigateur intégré pour saisir des informations de connexion.

Vous pouvez également utiliser un navigateur externe. Il y a plusieurs façons d'y parvenir. Certains nécessitent un peu plus d'intégration du système d'exploitation que d'autres. Certains exigent que vous ayez un service Web externe fonctionnant à côté (ou du moins accessible par) votre serveur de jeu principal. Notez que puisque Facebook et Google nécessitent généralement une URL authentifiée, vous aurez besoin d'une page de destination de site Web public pour utiliser ces protocoles dans (presque) tous les cas.

Le plus sûr et le plus fiable, sinon le plus simple, est de faire rebondir votre demande de connexion de votre client via votre site Web principal. Votre client se connecte au serveur de jeu principal en tant qu'utilisateur invité authentifié et reçoit un jeton de session unique. Le serveur de jeu ne permet pas au client de faire réellement beaucoup de choses dans cet état; le jeu ne sait pas qui est le joueur, donc le joueur ne peut pas encore discuter, commencer un match, etc.

Le client lance ensuite le navigateur externe pointant vers l'URL de connexion du domaine de votre jeu, en passant ce jeton de session comme paramètre dans l'URL. Le site passe ensuite par la procédure de connexion habituelle pour Facebook / Google.

À ce stade, votre serveur Web sait que l'utilisateur s'est connecté et peut l'associer au jeton de session qu'il a reçu du client. Cette vérification peut ensuite être communiquée au serveur de jeu, élevant la connexion d'invité non authentifiée du client en une session utilisateur authentifiée. Cela peut être fait en faisant communiquer le serveur Web directement avec le serveur de jeu, si possible. Ou le serveur de jeu peut périodiquement interroger le serveur Web pour connaître le statut d'authentification des connexions invitées en attente. Ou le client peut périodiquement interroger le serveur Web pour voir si la connexion est terminée et, quand c'est le cas, signaler au serveur de jeu de demander une vérification au serveur Web.

Tous ces éléments nécessitent que votre serveur de jeu et votre serveur Web puissent communiquer, mais tout service d'authentification tiers nécessitera que votre serveur de jeu puisse communiquer avec le monde extérieur, cela ne devrait donc pas être une surprise.

Cette méthode d'authentification se trouve dans certains MMO de petite à moyenne taille.

Notez que tout cela fonctionne également pour effectuer des demandes de paiement via un service externe, comme PayPal, Amazon Payments, Google Wallet, etc.

Connexion TLS directe

Il n'est pas trop difficile de démarrer une session TLS via un protocole de flux personnalisé. Des bibliothèques comme OpenSSL, GnuTLS, NSS et diverses bibliothèques spécifiques au système d'exploitation fournissent une API de wrapper de flux qui se superpose à un transport / protocole de bas niveau. Vous avez généralement juste besoin de nourrir les octets via l'API wrapper et il traite de la poignée de main et du chiffrement.

Les parties délicates ici garantissent que votre utilisation de TLS est sûre. Par exemple, certaines bibliothèques courantes nécessitent par défaut un certificat signé valide d'une autorité de confiance. Certaines bibliothèques communes l'exigent, mais par défaut, ne font confiance à aucune autorité. Certains d'entre eux n'exigent pas que le certificat soit valide du tout.

Il est recommandé de toujours exiger un certificat valide. Autoriser des certificats invalides ne permettra pas à un attaquant qui espionne simplement de voler un mot de passe, mais cela autorisera toujours les attaques de l'homme du milieu.

Cette approche requiert le moins absolu en termes de dépendances externes tout en permettant une sécurité maximale.

Des exemples de jeux utilisant cela incluent maintenant la plupart des grands MMO traditionnels.

Jeux traditionnels sécurisés

Les jeux qui n'utilisent pas de service séparé et n'utilisent pas TLS doivent généralement implémenter une sorte de protocole de connexion non basé sur leur dans leur protocole de jeu principal. Avec cette méthode, le serveur génère un nombre aléatoire (un nonce) et l'envoie au client. Le client hache ensuite ce nonce avec le mot de passe de l'utilisateur (et le nom d'utilisateur, éventuellement d'autres données) et envoie cette réponse au serveur. Le serveur compare ensuite cette valeur hachée avec les informations d'identification qu'il possède dans le fichier. Cela garde le mot de passe de l'utilisateur secret sur le fil et garantit que vous ne pouvez pas utiliser une attaque de relecture simple sur le mot de passe haché, comme de nombreux autres schémas de connexion basés sur le hachage.

Un problème est que l'utilisateur n'a aucun moyen de soumettre un nouveau mot de passe au service via ce protocole en toute sécurité. Les implémentations typiques stockent également le mot de passe de l'utilisateur en texte brut sur le serveur, ce qui est une pratique horrible (si votre serveur est piraté, votre utilisateur vient probablement de se faire voler son mot de passe e-mail / facebook / banque, car il utilisait le même mot de passe pour votre jeu que partout ailleurs, car les utilisateurs ont tendance à le faire).

Il existe des versions améliorées de ce schéma de connexion de base. Le plus élémentaire - bien qu'il ne soit toujours pas idéalement sécurisé - est que le serveur envoie le sel de hachage du mot de passe avec la valeur nonce lors de la connexion. Cela permet au serveur de stocker un mot de passe haché (et salé) en toute sécurité tout en permettant au client de générer le même hachage lors de la connexion. Cela permet à un attaquant d'obtenir le sel pour le mot de passe d'un utilisateur particulier, mais cela n'est pas particulièrement utile sans obtenir également le mot de passe haché d'origine (qui n'est pas envoyé sur le fil lors de la connexion). Lors de la création / mise à jour du mot de passe, le client envoie l'intégralité du mot de passe haché (avec salt), que l'attaquant peut renifler. Si la fonction de hachage utilisée est suffisamment forte (par exemple, sha-2/512), le forçage brut pur n'est pas possible, bien que l'attaquant puisse toujours facilement utiliser des mots de passe faibles par force brute (c'est pourquoi il est important d'appliquer une longueur minimale de mot de passe, une distribution minimale de lettres / chiffres / symboles et de comparer avec un dictionnaire de mots de passe connus / évidents / faibles). Le fait que l'attaquant puisse toujours obtenir le mot de passe haché est la raison pour laquelle il est encore plus sûr de procéder à l'échange complet du mot de passe sur un canal sécurisé et crypté.

Un certain nombre de bibliothèques de mise en réseau de jeux populaires implémentent une forme facultative de ce protocole. Je crois que SmartFox en est un exemple, bien que je ne l'ai pas examiné en profondeur (j'ignore généralement un tel système d'authentification de bibliothèque et j'utilise la méthode HTTPS, car il est morte à mettre en œuvre et beaucoup plus fort). Un certain nombre de premiers jeux Internet non Web ont également utilisé cette approche, en particulier avant que Steam, XBL, etc.

Jeux traditionnels non sécurisés

Beaucoup de jeux envoient malheureusement un nom d'utilisateur / mot de passe en clair. Peut-être qu'ils hachent le mot de passe, ce qui protège vaguement le mot de passe réel des utilisateurs (pas assez bien) mais une attaque de relecture rend la connexion au service de jeu triviale.

Ne fais pas ça. C'est irresponsable et paresseux. La naïveté d'Internet des années 1990 qui a popularisé ces méthodes de connexion n'est plus une excuse viable.

De nombreux jeux Flash et Web antérieurs à Facebook ont ​​adopté cette approche. Je ne connais aucun exemple précis du haut de ma tête; J'aimerais croire qu'ils sont tous morts depuis longtemps, mais le monde n'est tout simplement pas aussi chanceux.

Pas d'authentification

La plupart des jeux ne font tout simplement pas d'authentification. Le joueur se connecte, envoie une poignée pour s'identifier de manière unique, et un match commence. Il n'y a pas de serveur global qui essaie de valider qu'un seul humain réel est autorisé à prétendre être "CaptainMisterDude". Le serveur local s'assure simplement qu'un seul joueur actuellement connecté a une poignée particulière, et c'est la fin. Les serveurs locaux utilisent une liste noire basée sur le nom et sur IP pour les fauteurs de troubles. Cela est courant pour les jeux de style FPS deathmatch, même aujourd'hui.

Si vous n'avez pas besoin d'un état permanent pour les comptes, c'est de loin la solution la plus simple et assez "sécurisée" car il n'y a rien à pirater ou à voler. Évidemment, cela ne fonctionne pas trop bien si vous avez besoin de stocker des informations de compte entre les sessions de jeu.

Quake est un exemple de jeu utilisant cette méthode "d'authentification" des utilisateurs.

Sean Middleditch
la source
1
Pourquoi écrivez-vous autant sur HTTPS? HTTP n'est pas particulièrement adapté à un protocole de jeu. Un protocole binaire spécialement conçu dans un tunnel TLS devrait être la voie à suivre.
aaaaaaaaaaaa
10
Pour vous connecter? C'est parfaitement adapté. Vous ne vous connectez pas 30 fois / seconde. Vous vous connectez une fois lorsque vous démarrez le client, puis vous avez terminé. La connexion HTTPS renvoie un cookie que le protocole binaire spécialement conçu utilise pour authentifier la connexion sans avoir besoin du mot de passe lui-même.
Sean Middleditch du
1
Ce n'est pas parce que ce n'est pas un problème de performances que cela signifie que ce n'est pas une approche gonflée qui ajoute une complexité inutile.
aaaaaaaaaaaa
4
J'utiliserais exactement les mêmes mots pour décrire votre approche proposée. À chacun ses goûts. :)
Sean Middleditch
2
Donc, incluriez-vous une bibliothèque HTTP entière pour envoyer 2 chaînes dans un sens et en récupérer 1, ou implémenteriez-vous vous-même le sous-ensemble HTTP requis, y compris la gestion des séquences d'échappement?
aaaaaaaaaaaa
3

SSL aiderait les clients à identifier les serveurs légitimes, contre les "faux" serveurs, en utilisant un certificat de serveur signé par une autorité de certification connue. Je soupçonne fortement que la plupart des jeux ne prennent pas la peine de le faire.

Il y a cependant de bonnes raisons pour lesquelles ils pourraient vouloir. Certains mécanismes d'évitement de licence / de triche peuvent fonctionner en utilisant un serveur escroc ou un serveur "homme au milieu".

Je m'attends à ce que les principaux réseaux multijoueurs tels que Steam et Microsoft disposent d'une telle protection intégrée.

Un jeu basé sur le Web peut simplement utiliser HTTPS, mais je ne sais pas si cela fonctionne pour Websockets (un trivial Google devrait y répondre).

MarkR
la source