ブラウザゲームにおけるセーブデータの保存と改ざん防止対策
🔒 この記事のポイント:ブラウザゲームのハイスコアやゲーム内通貨などのデータ保存で最も使われるLocalStorageは、F12キー(デベロッパーツール)で誰でも簡単に書き換えられてしまいます。ゲームの健全性を守るためのデータ暗号化と検証ロジックを解説します。
LocalStorageとは?ブラウザセーブデータの基本
アプリのインストールを必要としないブラウザゲームにおいて、プレイヤーのハイスコア、ステージのクリア状況、獲得したアイテムなどのデータを保存する仕組みとして、最も使われているのがブラウザの「LocalStorage(ローカルストレージ)」です。
LocalStorageは、キーと値のペア(Key-Value Store)を単純な文字列データとしてユーザーのブラウザ内に永続保存できる非常に便利なWeb APIです。ブラウザを閉じたりPCを再起動したりしても、同一ドメインであれば次回アクセス時にもデータを保持し続けることができます。
LocalStorageの最大の弱点
開発者にとって非常に簡単なLocalStorageですが、セキュリティの観点では「最悪の選択肢」になり得ます。なぜなら、**ユーザーはデベロッパーツール(F12キー)の「アプリケーション」タブから、保存されている値を完全に自由に、1秒で直接書き換えることができるから**です。
例えば、ハイスコアを保存するキーが `highScore: 120` と生データのままLocalStorageに入っていた場合、ユーザーがその値を `9999999` に書き換えてランキング送信ボタンを押せば、チートによるデタラメなスコアがサーバーに送信され、ランキング全体の信頼性が完全に崩壊してしまいます。
クライアントサイドで行うデータの改ざん対策
サーバーレスで動作する手軽なゲームでは、完璧な不正防止は難しいですが、「普通のプレイヤーが悪意なく簡単に値を書き換えられてしまう状態」を強固に防御することは十分に可能です。効果的な3つのセキュリティアプローチを紹介します。
1. セーブデータの暗号化(CryptoJS / AES)
データを生テキストのままLocalStorageに書き込まず、JavaScript上で暗号化してから保存します。最もポピュラーなのが、高度な対称鍵暗号アルゴリズム「AES(Advanced Encryption Standard)」を用いた暗号化です。
外部ライブラリである `CryptoJS` をCDNなどから読み込み、セーブデータをシリアライズした上で暗号化キーを渡して暗号化します。
// 保存時の暗号化
const saveState = { score: 2500, level: 5 };
const secretKey = "studio-portal-secure-key"; // 難読化したスクリプト内に隠す
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(saveState), secretKey).toString();
localStorage.setItem('game_save', encrypted);
// 読み込み時の復号化
const cipherText = localStorage.getItem('game_save');
if (cipherText) {
const bytes = CryptoJS.AES.decrypt(cipherText, secretKey);
const decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
console.log(decryptedData.score); // 2500
}
これにより、デベロッパーツール上には不規則なハッシュ文字列のみが表示されるようになり、プレイヤーが数値を直接変更することが実質的に不可能になります。
2. チェックサム・ハッシュによる整合性検査(HMAC)
データ自体はそのまま、もしくはBase64で保存しつつ、データ改ざん検出用の「署名(デジタル署名)」を同時に書き込む方法です。
`データ文字列 + 秘密の文字列(ソルト)` をSHA-256などのハッシュ関数に通してハッシュ値を作成し、データと一緒にLocalStorageに保存します。ロード時に再度同じ方法でハッシュ値を算出し、一致しなければ「改ざん検知」と判定してデータをリセットします。
3. ソースコードの難読化(Obfuscation)
暗号化キーやハッシュ用の文字列(ソルト)がクライアントサイドJavaScriptに書かれている以上、上級のハッカーはJavaScriptファイルを開いて暗号鍵を特定する可能性があります。
これを防ぐために、本番ビルド時には必ず **JavaScript難読化ツール (Terser や javascript-obfuscator)** を使用し、変数の文字列や制御フローを複雑にして、ソースコードの解析の難易度を極限まで高めておきます。
まとめ
クライアントサイドで動作するブラウザゲームにおいて、100%完璧にハッキングを防ぐ魔法はありません。しかし、「暗号化」「ハッシュ検証」「コード難読化」の3つを適切に組み合わせることで、99%以上の不正改ざん行為を阻止し、ポータルサイトのランキングの公平性と価値を守り抜くことができます。正しい知識を持って、安全で楽しいゲームサイトを構築しましょう!