Authentification pour un jeu multijoueur via des sockets

11

J'implémente un protocole binaire personnalisé pour un nouveau jeu multijoueur sur lequel je travaille. C'est un jeu de stratégie au tour par tour, donc le timing n'a pas vraiment d'importance. J'ai actuellement la partie de synchronisation de données de base du système terminée, et je me demandais comment la connexion / déconnexion et le cryptage des utilisateurs sont généralement effectués pour les jeux MMORPG ou similaires.

  • Pouvez-vous recommander un schéma de transmission de mot de passe sécurisé / secret lors de la connexion? (Échange de clés Diffie-Hellman?)
  • Comment implémenter un cryptage fort pour les paquets de données? (AES 128 bits? .. ou quel que soit le schéma que cet article qualifie de "cryptage plus fort que vous êtes susceptible de craquer")
  • Existe-t-il des schémas de format de datagramme qui aident à durcir le serveur de jeu pour rejouer les attaques, les paquets de données invalides et similaires?
Robinicks
la source

Réponses:

15

Réponses

  • SRP - Secure Remote Password - Il est basé sur Diffie-Hellman. L'idée est que vous pouvez effectuer une vérification mutuelle du mot de passe sans jamais transférer le mot de passe ni aucune information pouvant être utilisée pour le dériver. Même s'il est sécurisé sur le fil, vous devez toujours hacher et saler vos mots de passe car votre serveur ne doit jamais les stocker en texte brut .
  • L'avantage de SRP est qu'une fois terminé, il vous donne également une clé de chiffrement négociée mutuellement qu'un attaquant n'aurait pas pu déduire compte tenu des données que vous avez transférées. Cela signifie que vous êtes libre d'utiliser un algorithme de chiffrement symétrique (comme AES) une fois que l'utilisateur est authentifié.
  • En supposant que vous utilisez UDP avec votre propre implémentation fiable / ordonnée (orientée connexion), cryptez la totalité de la charge de lecture UDP, y compris votre `` numéro de séquence de paquets ''. Si votre système est conçu correctement, il rejettera automatiquement les messages rejoués et un intrus ne pourra pas changer le numéro de séquence des paquets car il est chiffré (donc une relecture est possible - mais elle serait automatiquement ignorée).

Pensées

Votre authentification doit-elle être sécurisée? Absolument. Ne faites aucun compromis en termes de sécurité lorsqu'un mot de passe est en question. Ainsi, vous devriez certainement considérer la première puce de ma réponse.

Vos données doivent-elles être sécurisées? Seulement s'il s'agit d'un achat / d'une micro-transaction dans le jeu - et alors pourquoi ne pas simplement utiliser quelque chose qui a fait ses preuves comme HTTPS. Le chiffrement de votre trafic de jeu n'est probablement pas une solution viable pour les raisons suivantes:

  • C'est la paranoïa complète.
  • Cela va ajouter une surcharge de temps CPU sur votre serveur, sauf si vous pouvez acheter des modules de chiffrement matériel (coûteux).
  • Peu importe le niveau de sécurité que vous fournissez pour vos données sur le câble - quelqu'un pourrait détourner le processus client et intercepter les messages au moment où ils sont cryptés et envoyés. C'est non seulement une possibilité mais infiniment plus possible car il est beaucoup plus facile d'injecter du code que d'intercepter des paquets. Si vous faites cela pour prévenir la triche, vous perdez complètement et complètement votre temps.
    • En termes de sécurité par mot de passe, il n'y a malheureusement rien que vous puissiez raisonnablement faire contre un système piraté, le client est devenu hostile. Les dongles Blizzards WoW sont conçus pour faire face à cela - mais je ne suis pas sûr de la sécurité (surtout si vous le laissez branché).

S'il vous plaît, si vous chiffrez pour la prévention de la triche, abandonnez-le. Vous allez être bref - je vous ai donné les informations au cas où vous ne le seriez pas. N'oubliez pas que vous pouvez chiffrer sélectivement les paquets par le premier octet dans le paquet et indiquer si le reste est chiffré: bien que, une fois de plus, je m'en tiendrais au HTTPS si vous devez faire des choses comme les transactions par carte de crédit: elles sont extrêmement rares et HTTPS est conçu par des experts - contrairement à quelque chose que vous ou moi avez conçu.

Cela dit, Blizzard crypte réellement leur trafic WoW. La principale raison de cette rupture est que quelqu'un, qui est probablement un amateur complet, a décidé de s'essayer à un algorithme de cryptage maison; cela a très bien fonctionné . Même si vous utilisez des algorithmes standard de l'industrie, il y a de fortes chances que quelqu'un procède à une rétro-ingénierie de votre code et le simule - une fois que le client a entré son mot de passe, rien ne dit qu'un système non pris en charge est connecté.

Jonathan Dickinson
la source
2
+1 pour dire que le cryptage des paquets de données pour la prévention de la triche est inutile. OP: vérifiez tout ce que vous recevez du client, effectuez des vérifications de santé mentale, vérifiez si l'action demandée par le client est possible, vérifiez la portée des armes, la vitesse de déplacement, etc. mais ne perdez pas de temps à sécuriser votre client car il sera piraté si votre jeu en vaut la peine. Certaines sociétés MMO chiffrent et obscurcissent leurs clients / protocoles, mais ce n'est pas pour empêcher la triche, mais pour rendre plus difficile, par exemple, aux créateurs de robots d'obtenir de bons résultats, et même cela est fait par des équipes d'experts dédiées.
Gilead
1
Une petite critique concernant votre troisième réponse: le simple chiffrement des paquets peut ne pas être suffisant pour empêcher la falsification, car de nombreux schémas de chiffrement sont au moins quelque peu malléables . Pour protéger l'intégrité des messages, vous avez besoin d'un MAC ou d'un mode de chiffrement authentifié .
Ilmari Karonen
+1 Merci pour une réponse très complète. Vous cherchez à implémenter SRP en ce moment. Quelles sont vos recommandations concernant la fonction de hachage utilisée pour les mots de passe? MD5? Comment serait le protocole OTR (Off the Record) pour un tel cas d'utilisation? cela fonctionnerait-il bien pour auth / crypto au lieu de SRP? Si j'utilise SRP, devrais-je utiliser l'un des modes de "cryptage authentifié" suivants? (OCB 2.0, Key Wrap, CCM, EAX, Encrypt-then-MAC et GCM)
Robinicks
1
@Jenko utilise la famille d'algorithmes SHA (probablement SHA1) - vous devriez éviter MD5 de nos jours. OTR n'est vraiment pas quelque chose que vous devriez regarder - il n'est pas conçu pour être sécurisé / obscur (en fait, il est conçu pour que quelqu'un puisse plus facilement forger des paquets), il est également conçu pour la messagerie instantanée et non pour la communication avec la machine. Aucun de ces modes n'est nécessaire, utilisez simplement SRP: une fois que vous avez une clé symétrique négociée mutuellement, le simple fait de pouvoir chiffrer quelque chose est une garantie suffisante que vous parlez au bon tiers. Aussi, encore une fois, relisez mes deux derniers paragraphes.
Jonathan Dickinson
1
En fait, j'ai une suggestion encore meilleure: utilisez une implémentation DTLS existante sur UDP et n'essayez pas de lancer la vôtre. Cela vous fera gagner du temps et il y a beaucoup de petits détails critiques qui sont faciles à se tromper si vous essayez de concevoir votre propre couche de chiffrement de datagrammes.
Ilmari Karonen
2

Je pense que mon dernier commentaire à la réponse par ailleurs excellente de Jonathan mérite d'être développé en une réponse à part:

Si vous n'avez pas beaucoup d'expérience en cryptographie, vous ne devriez pas essayer de concevoir votre propre couche de cryptage si vous pouvez l'éviter. Si vous n'avez beaucoup d'expérience Crypto, vous devriez savoir mieux que de concevoir votre propre couche de cryptage si vous pouvez l' éviter.

Au lieu de cela, essayez de trouver une bibliothèque de chiffrement existante, normalisée et bien testée qui fait ce dont vous avez besoin. Dans votre cas, je recommanderais GnuTLS , qui, selon Wikipedia , fournit à la fois une authentification TLS-SRP ( RFC 5054 ) et une communication UDP sécurisée avec DTLS ( RFC 6347 ). Le premier se charge de la connexion, tandis que le second protège le canal sécurisé ainsi formé des écoutes et des attaques actives, et peut même vous protéger contre les attaques par rejeu .

Ilmari Karonen
la source
J'utilise TCP. Il s'agit d'un type de jeu très différent pour un client spécifique. Semblable au jeu / paris, toutes les informations qui peuvent être utilisées pour détourner le processus augmentent les chances de pertes inutiles par la maison. Nous devons garder les données extrêmement sécurisées, car l'information est de l'argent dans ce cas.
Robinicks
OK, si vous utilisez TCP, c'est encore plus facile: vous pouvez utiliser TLS 1.2 normal au lieu de DTLS, ce qui vous donne plus d'options à choisir. Je recommanderais quand même la bibliothèque GnuTLS.
Ilmari Karonen
Je vais faire un peu de recherche et voir si je peux me référer au code source TLS à la fois côté client et côté serveur, et baser mon protocole sur ce qu'il fait. Serait-ce assez fort? Essentiellement son cryptage de paquets juste avec un chiffrement / mode, correct?
Robinicks
Non, le protocole TLS en propose bien plus. C'est pourquoi vous souhaitez utiliser une bibliothèque standard qui l'implémente, au lieu de rouler la vôtre.
Ilmari Karonen