質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

ゲームのランキングサーバのチート対策に関する質問

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,071

take_create

score 7

前提・実現したいこと

スマホゲームのランキングサーバのチート対策を実現しようと考えています。具体的には、ユーザがクライアント側でゲーム(例えばシューティングゲーム)を行い、ゲーム終了時のスコアを 
{ "user_id": 123456789, "score": 34567} 
のようなパラメータでサーバに送信してもらいます。ユーザがゲームをするクライアントはブラウザ・iOS・Androidの3つに対応させようとしています。

調査したこと

スコアを送信する際に、通信データを偽装することでスコアを異常に高くするなどのチートが可能になってしまいます。チート対策の分かり易い資料として、以下のスライドがあります。

一般的なチートの手法と対策について
http://www.slideshare.net/ssuser741a3c/ss-62940759

この資料では通信データ偽装への対策としてハッシュを用いる方法が解説されています。

  1. クライアント側で「送信データ」のハッシュ値を生成
  2. 「送信データ」とハッシュ値をペアで送信
  3. サーバ側で「送信データ」からハッシュ値を生成し、クライアントから送られてきたハッシュ値と一致することを確認

といった方法です。

疑問

上記の方法を用いると、「クライアントで行っているハッシュ値生成のアルゴリズムを秘匿できれば」という条件付きで通信データ偽装を防ぐ事ができるかと思います。しかし、ブラウザやAndroidではユーザがコードを見ることが可能なので、どんな処理でハッシュ値を生成しているか分かってしまいます。これを防ぐには、どのようにすればよいのでしょうか?難読化で処理を見にくくするしかないのでしょうか?

上記のスライドの方法以外でも、定石の手法などがありましたら教えて頂きたく思います。ふわふわとした質問になってしまいましたが、よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

質問文の記事はバイナリファイル化されたゲームが基準になっていますので、
ブラウザーゲームでは役に立たないでしょう。

ブラウザゲーム時代のチートとセキュリティ
この辺からわかるように、ユーザーには権限は与えないのが一番の対策です。
まぁ、パケットをインターセプトする輩をJavaScriptで止める方法はないと考えた方が良いでしょうね。


話は少し変わりますが、将棋では棋譜、麻雀では牌譜と言うものがあることはご存知でしょうか?
これは元々感想戦という勝負時の取捨選択の結果を書き起こしたものですが、
コンピュータ上で再現されたこれらのゲームはテキストファイルとして書き起こしてログとしても使う事が出来ます。

実際にネット将棋や麻雀のサーバーではこの棋譜や牌譜を保存することで、
対局してないのに勝利するチートや、手牌を改ざんして役満をあがり続ける行為への対策としています。

上記を応用して、再現可能なログファイルにまでゲームを落とし込む事ができれば、
ある程度のチートは防ぐ事が可能です。

上記の手法を応用して、例えば対戦格闘ゲームやシューティングゲームは、
時間軸というタイミングを伴った完全情報ゲームに置き換える事が可能です。


以下は余談ですが、RPGやすごろく等の乱数も制御が可能です。
例えばRPGでは電源を入れた瞬間からの時間で乱数が決まる事を利用したテクニックがいくつもあります。
(特定の場所でセーブして、電源入れながら下を押し続けて戦闘に入りAボタン押しっぱなしにすると会心の一撃が必ず出てボスを倒せるとかね…)
いただきストリート2というゲームでは超長い乱数表が既に存在しており、何度リセットしても必ず同じサイコロの出目の順番でゲームが進行する仕組みになっています。

その中でも風来のシレンと同じ仕組みを構築することをおすすめします。
フロアに降り立った時、その瞬間の主人公の状態、フロアや敵の状態、乱数表が全て保存されます。

主人公がそのフロアの冒険中、毎ターン行った操作のみをログファイルとして作成し、セーブデータに吐き出します。
もし電顕を落とした場合、後からロードすると、フロアに降り立った後の冒険をログファイルを元に書き出して再現します。
なので一定数以上同じフロアに留まろうとすると、地震や風が吹いてそのフロアから追い出されてしまう仕組みなのですね。
(まぁこれ自体は風来のシレンのセーブ用RAMの少なさを解決するテクニックだったわけですが…)

クライアントから送信されたログファイルと、サーバー上にあるゲーム開始時のステータス・乱数テーブルの3つさえあれば、
そのプレイヤーが取りうる理論上行える最善のプレイ以上の結果は出せなくなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/23 19:15

    結論です。

    通信内容は重くなりますが、復元可能な操作履歴もログとして送ってもらうようにし、
    後から妥当か否かでチェックして、妥当なプレイ結果な事が確認出来た場合に限りランキングに載せるようにするということは出来るかと思います。

    キャンセル

  • 2016/12/23 19:39

    大変分かり易い説明をありがとうございました。
    ユーザーの行動ログを全てサーバーで検査すればよいのですね…
    貼って頂いたリンクも非常に参考になりました。
    疑問が全て解決したため、ベストアンサーに選出させて頂きました。

    キャンセル

  • 2016/12/23 20:12

    疑問が解決して良かったです。
    今思いつきましたが、ハイスコアを出した時だけログ出させたり、ログを圧縮したり、ある程度の妥当性を担保しつつ情報を間引いたり…という風に色々工夫できそうですね。
    ゲームが完成するのを楽しみにしてます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る