Partage
  • Partager sur Facebook
  • Partager sur Twitter

Communiquer avec un serveur de manière sécurisée

Leader-board en ligne

    25 septembre 2017 à 21:14:45

    Bonjour,

    Je suis dans le développement d'un jeu vidéo et je souhaite créer un leaderboard en ligne via une BDD.
    Chaque joueur possède un nom d'utilisateur et un mot de passe et peux se connecter au jeu via ces derniers. En lecture je n'ai pas de problème à visualiser la méthode (que ce soit via un script PHP ou une application serveur).

    Mais en écriture, dans mon cas pour le leaderboard, je n'arrive pas déterminer comment le faire de manière a éviter la triche. En effet, le code étant décompilable, le joueur peut communiquer avec le serveur via sa propre application avec son nom d'utilisateur et son mot de passe. Il peut donc entrer des valeurs extrème et fausser le leaderboard.
    Je ne peux pas crypter les données, puisqu'en décompilant on peut avoir acces à la méthode de cryptage, même avec une clef il faut bien qu'elle soit écrite quelque part.

    J'ai pensé a un système de tokken, donné à l'utilisateur lors de la connexion, mais le problème est le même. Le joueur peut récupérer le token dans la RAM et le réutiliser de la même façon.

    Peut-être envoyer un objet sérialisé, qui ne peut être interprété que via la même structure de classe ? Mais ça ne change pas le problème, on peut l'imiter.

    Finalement, comment faire ?
    Je vous remercie d'avance pour vos réponses.

    -
    Edité par TheZopo 25 septembre 2017 à 21:15:58

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      26 septembre 2017 à 10:37:38

      > Je ne peux pas crypter les données, puisqu'en décompilant on peut avoir acces à la méthode de cryptage, même avec une clef il faut bien qu'elle soit écrite quelque part.

      On dit chiffrer, pas crypter.

      Tu peux simplement envoyer les actions utilisateur au serveur et calculer les valeurs côté serveur, mettant la gestion des actions côté serveur (forte dépendance, pas forcément sympa)

      • Partager sur Facebook
      • Partager sur Twitter
        26 septembre 2017 à 16:10:14

        Ça manque d'informations sur le contexte.. Je pars du principe que :

        - c'est un jeu uniquement solo

        - a chaque fin de partie, le jeu envois à un serveur son score.

        Le problème n'est pas tant d'éviter la triche que de la détecter. En effet, il est impossible de s'assurer que le client envois les bonnes informations (programme décompilé etc...), on ne peut donc pas éviter la triche... C'est d'ailleurs là le B A B A d'une architecture client / serveur : ne jamais faire confiance au client, et tout calculer coté serveur. Mais ça pose problème quand le jeu est solo....

        L'idée est donc de détecter les tentatives de triches à posteriori. Pour ça, il faut d'abord être sur de pouvoir identifier tous les accès -> connexion sécurité (HTTPS) et authentification par login / password ou token unique.

        Ensuite, il faut donner au serveur les moyens de savoir si le résultat envoyé "semble" correct. Un moyen naïf est de refuser les scores trop haut (ex: 9999999). Ça se contourne aisément (car il suffit de tenter avec un nombre moins grand) mais l'idée est là : bannissement du compte (de manière auto, au moins provisoire avant intervention humaine) en cas de valeurs ne pouvant résulter que d'une tentative de triche.

        Dans cet exemple, la solution est très simple (d'où le fait que l'approche soit naïve) car on ne test que le résultat final: le score.A l’extrême inverse, l'idée est d'envoyer le record complet de la partie au serveur. Celui-ci rejoue alors intégralement la partie et vérifie que le score obtenu est bien celui envoyé. Là, l'idée est d'accepter immédiatement le score envoyé par le joueur (pour ne pas le frustrer), mais de le vérifier en tâche de fond par le serveur.

        Cette solution est "parfaite", mais beaucoup plus complexe (surtout si le jeu n'est pas déterministe), voire impossible à obtenir en pratique (impossible de rejouer plusieurs centaines de partie en même temps coté serveurs, limite de la puissance de calcul etc...).

        Entre les deux, il y a des compromis à faire entre exhaustivité du calcul, et complexité. Une solution pourrait être de faire durant la partie des "checkpoints", avec l'état du joueur, son score etc... et envoyer le tout en même temps que le score final. Le serveur doit alors interpoler les différents checkpoints, et vérifier la cohérence du déroulement de la partie avec le score final.

        • Partager sur Facebook
        • Partager sur Twitter
          28 septembre 2017 à 17:42:21

          C'est effectivement un jeu uniquement solo, avec leaderboard en ligne (Comme Osu par exemple).
          Merci pour ta réponse, je n'avais pas pensé à l'idée des checkpoint, il faut que je réfléchisse a comment l'implémenter. En espérant que les joueurs ne partagent pas leurs partie, (de quelques façons que ce soit) pour en faire profiter d'autres.
          • Partager sur Facebook
          • Partager sur Twitter
            29 septembre 2017 à 15:14:03

            Pour ça, il faut pouvoir authentifier une partie / un checkpoint.

            L'algorithme HMAC https://fr.wikipedia.org/wiki/Keyed-Hash_Message_Authentication_Code est la meilleure solution. C'est quasiment disponible dans tous les language.

            C'est un peu comme si on hashait un message, avec le mot de passe en sel. On envois que le message, et le hash. Le serveur recalcul le hash à partir du message, et du sel qu'il a lui aussi de son coté. Si les deux hash sont identique, alors on sait que c'est bien le bon utilisateur qui a envoyé le message.

            Enfin, c'est le principe. Il vaut mieux utiliser hmac qui est vraiment fait pour ça, plutôt que de bidouiller quelque chose qui sera moins sécurisé.

            Ca nécessite toutefois d'avoir un secret partagé, et que le message change à chaque fois. Le message doit donc contenir la partie/checkpoint, mais aussi le nom de l'utilisateur. On peut également rajouter un timestamp. Le serveur ne devant pas accepter deux fois le même timestamp (dans le cas où un pirate intercepte le apcket, et le renvois tel quel; sans le modifier, il serait valide), rendant impossible de "rejouer" un packet reçus.

            Pour la clef secret, il vaut mieux envoyer utiliser une clef dérivée du mot de passe. Un hash (avec sha2 par exemple) peut convenir.

            -
            Edité par Sebajuste 29 septembre 2017 à 15:16:27

            • Partager sur Facebook
            • Partager sur Twitter

            Communiquer avec un serveur de manière sécurisée

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown