🌟

UnityでAES暗号化を導入する: ローカルデータを「少しでも」安全に扱うコツ

2025/01/23に公開

UnityでAES暗号化を導入する: ローカルデータを「少しでも」安全に扱うコツ

なぜAES暗号化が必要か?

ゲーム開発やアプリ開発をしていると、APIキーやユーザー名、スコアなどのデータをローカルに保存しなくてはならない場面があります。単に「PlayerPrefsに文字列として保存」するだけでは、ファイルやレジストリを直接覗かれたときに まる見え になってしまう可能性が高いわけです。

そこで登場するのがAES暗号化。C#標準のライブラリ(System.Security.Cryptography)で提供されているため、自前で複雑な暗号ロジックを書く必要がない点がメリットです。もちろん、キーやIVをローカルに置いている限り、本格的なセキュリティとしては万全ではありませんが、「ちょっと隠しておきたい」程度の対策には十分役立ちます。

どんな問題を解決できるのか?

  • APIキーが平文で書かれていると、改変や盗用リスクがある
  • ゲーム内のステータスやセーブデータを改ざんされたくない(数値を勝手にいじられるなど)
  • ユーザー情報や課金関連の一部を、完全オフラインで少しでも安全に保持したい

AES暗号化を導入すれば、最低限のハードルを設けられます。何も対策しないよりは、改ざんや盗用のコストを上げられるわけです。

AES暗号化の基礎: C#のサンプルコード

以下は、C#でAES暗号化する最小限の例です。Unityプロジェクトでも同じように使用できます。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class AESTool
{
    // 実際には、キーとIVは安全に管理する必要があります
    private static readonly byte[] key = Encoding.UTF8.GetBytes("1234567890ABCDEF1234567890ABCDEF");
    private static readonly byte[] iv  = Encoding.UTF8.GetBytes("ABCDEF1234567890");

    public static string Encrypt(string plainText)
    {
        using(Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV  = iv;
            using(var ms = new MemoryStream())
            {
                using(var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    byte[] bytes = Encoding.UTF8.GetBytes(plainText);
                    cs.Write(bytes, 0, bytes.Length);
                }
                // 暗号化した結果をBase64で返す
                return Convert.ToBase64String(ms.ToArray());
            }
        }
    }

    public static string Decrypt(string cipherText)
    {
        using(Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV  = iv;
            using(var ms = new MemoryStream())
            {
                using(var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    byte[] bytes = Convert.FromBase64String(cipherText);
                    cs.Write(bytes, 0, bytes.Length);
                }
                // 復号化したデータをUTF8文字列へ
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
    }
}
  • Encryptメソッド: 平文(プレーンテキスト)をAESで暗号化し、Base64文字列に変換
  • Decryptメソッド: Base64文字列をバイト列に戻し、AESで復号化してUTF8文字列へ

どう使う?Unityでの実装例

手順1: ランタイムで暗号化して保存

たとえば、APIキーやユーザーのトークンをPlayerPrefsに保存したい場合、以下のように暗号化してSetStringする方法があります。

public void SaveEncryptedData(string key, string plainValue)
{
    string encrypted = AESTool.Encrypt(plainValue);
    PlayerPrefs.SetString(key, encrypted);
    PlayerPrefs.Save();
}

手順2: 読み込み時に復号化

public string LoadEncryptedData(string key)
{
    string encrypted = PlayerPrefs.GetString(key, "");
    if (string.IsNullOrEmpty(encrypted))
    {
        return null; // データがない
    }
    return AESTool.Decrypt(encrypted);
}

こうすることで、PlayerPrefsをレジストリやファイルシステムで直接覗いても、すぐには分からない形にできます。

メリットと限界を整理しよう

メリット

  • XORなどの簡易方式に比べ、より安全性が高い
  • .NET標準APIが整備されているため、導入が容易
  • ちょっとした改ざん・流出対策としては有効

デメリット

  • ローカルにキーとIVを置く以上、完全防御にはならない
  • コードやアセットを解析されれば、キーを取り出されるリスクは残る
  • 暗号化処理自体はXORに比べてやや重い(とはいえ、頻繁に呼ばなければ問題なし)

気を付けたいポイント

  • キーとIVの管理: ベタ書きすると、逆コンパイルされれば丸見え。難読化ツールなどと組み合わせて、より解析を難しくするアプローチが有効
  • 書き込み回数: どんなに高速とはいえ、暗号化処理をゲームループ中に乱発するとパフォーマンスに影響が出る場合も。セーブやロードの頻度を考慮する
  • オンライン検証との併用: 本格的に不正防止したいなら、最終的にはサーバー検証が理想。ローカルの暗号化だけでは「時間をかければ解読可能」という大前提は覆せません
暗号化の更新を減らす工夫
  • ユーザーが設定を変更したときだけ暗号化 → 保存
  • 大きな連続セーブが必要な場合は、パラメータだけ暗号化し、細部は平文で持つ…など

まとめ: 「やらないよりは、やったほうがいい」暗号化

AES暗号化を導入すれば、ただの文字列保存よりは高いハードルを設定できます。APIキーや重要設定が丸見えになるリスクを少しでも減らしたいなら、XORよりはAESが無難です。もちろん、完璧な安全策とは言い難いですが、コードを読まれても即座に値を特定できないという点で、一定の改ざん対策にはなります。

ローカルで「どうしてもキーを持たざるを得ない」ケースは多いので、その際に難読化IL2CPPビルドなどと組み合わせると、さらに解析の難易度を上げられます。

最終的には、セキュリティレベルと開発コストをバランスすることが大事。オンライン検証やサーバー側の管理ができるなら、そちらを活用するのがベストです。しかしローカルオンリーでどうにかしたいなら、AES暗号化を試してみてはいかがでしょうか。

この記事を読んでもっと実践したいと感じたあなたへ

Unity開発を効率よく進めるためには、実践的なスキルと仲間との交流が欠かせません。
そんな方におすすめのステップが、下記の3つです。

1. 有料教材「どこでもUnity教室」でゲーム制作を短期マスター

  • 5日でシンプルなFPS完成:初心者向けに要点を押さえたカリキュラム
  • C#や最新のInputSystem、FPS実装まで網羅:つまずきやすいポイントを先回りで解説
  • 購入特典:Discord招待+サンプルプロジェクトDLで、疑問や実装例を即確認

Unity初心者でも最短5日で3D FPSが完成!今すぐ始める入門チュートリアルはこちら

https://zenn.dev/ryuryu_game/books/fd28de9d8e963a

2. 無料コミュニティで、疑問をすぐに解消&モチベーションUP

  • 初心者~中級者までOK:学習進度に合わせて質問や情報共有
  • 質問サポートが充実:わからないことを仲間や講師に即相談
  • 学習仲間と切磋琢磨:一緒に学ぶから続けやすい

Discordサーバー参加はこちら

https://discord.gg/5FwuKCacNy

3. 実績豊富な“ゲーム開発所RYURYU”があなたをトータルサポート

  • コナラ総販売200件超:さまざまなUnity開発の依頼を対応
  • VR/AR/AIなど最新技術にも精通:幅広いノウハウを活かして開発支援
  • ゲームクリエイター甲子園や東京ゲームショウなど出展実績多数

ご相談・お問い合わせはこちら

https://coconala.com/users/1772507

ローカルデータのAES暗号化は、完璧ではないにせよ「何も対策しないより確実に安心感が増す」やり方です。自分のプロジェクトにあわせて、必要なレベルの保護を実装してみましょう。どうしても迷ったら、コミュニティや専門家に相談するのも手です。ゲーム開発で大事なのは「リスクを完全ゼロにする」ことではなく、実現したい機能と安全性を両立する柔軟な姿勢かもしれません。

Discussion