Cocos Creatorのユーザーデータ暗号化

公式のユーザーデータ保存は参考1の通りですが、今回やりたいこととの違いは、①TypeScriptでの実装、②暗号化部分の情報補足の2点になります。

プロジェクトルートで下記コマンドでencryptjsをインストールすることができます。

npm i encryptjs

npmコマンドが見つからない場合はHomebrewなどで以下のようにインストールできます。

brew install node

encryptjsをインストールできたら、プロジェクトルート/node_modules/encryptjsのディレクトリーが増えると思います。

その下の「algo.js」と「encryptjs.js」があるはずですので、それらをドラックしてCocos Creatorの「Script」のようなフォルダに入れます。
※「Script」の下で、サードパーティライブラリ専用のサブフォルダを作り、その中に入れたほうがいいかもしれません。例として、Script/Libraryでいきます。

そしたら、こんな感じでユーザーデータ保存用クラス(UserData.ts)を作れます。

const {ccclass, property} = cc._decorator;
import * as Encrypt from '../Library/encryptjs'; // ここで先程追加したライブラリをインポート

@ccclass
export default class UserData extends cc.Component {

    private static _instance:UserData;
    private static secretKey:string = 'abab123'; // 暗号キー

    private constructor() {
        super();
    }

    // シングルトンの例
    public static get instance():UserData {
        if (!this._instance) {
            cc.log("Init UserData");
            this._instance = new UserData();
            this._instance.save();
            this._instance.load();
        }
        return this._instance;
    }

    public save() {
        // サンプルデータを作成
        let userData = {
            name: 'Tracer',
            level: 1,
            gold: 100
        };

     // JSONを文字列に変換
        let dataString = JSON.stringify(userData);
        cc.log("data 1: " + dataString);
     // 暗号化
        let encrypted = Encrypt.encrypt(dataString, UserData.secretKey, 256);
        cc.log("encryptd data: " + encrypted);
        // ローカルに保存
        cc.sys.localStorage.setItem('UserData', encrypted);
    }

    public load() {
        // ローカルに保存したデータの読込み
        let cipherText = cc.sys.localStorage.getItem('UserData');
        // 復号化
        let decrypted = Encrypt.decrypt(cipherText, UserData.secretKey, 256);
        // JSON解析
        let userData2 = JSON.parse(decrypted);
        cc.log("data 2 :" + JSON.stringify(userData2)); // ログ出力のために文字列に変換
    }
}

ここでは初期化のところに保存と読込みやってますが、必要に応じて場所を変えるといいでしょう。
実行してUserDataが初期化されると以下のようなログが出力されると思われます。

[Log] Init UserData (UserData.js, line 35)
[Log] data 1: {"name":"Tracer","level":1,"gold":100} (UserData.js, line 52)
[Log] encryptd data: iwPrvkfnzVuqXcF48BFHIXyOYwGJ2Uvma/yNL3dx2iPyWyQmQ/DEhB9POIlt1g== (UserData.js, line 54)
[Log] data 2 :{"name":"Tracer","level":1,"gold":100} (UserData.js, line 61)

ユーザーデータの暗号化は以上です。

ところで、最終的にネイティブで実行されるコードはJavaScriptである故に、バイナリにならず、.jscの付いたソースコードを難読化したものにとどまります。
ソースコードの難読化は暗号化ではなく、ソースコードの復元は比較的に容易にできるはずです。
さらに、もしCocos CreatorでWebブラウザ向けのゲームを作るなら、難読化すらされず(難読化されたらブラウザが読めなくなるため)、ソースコードそのまま公開されます。
これはCocosだけの問題ではなく、どのエンジンでも、プラグインなしではHTML+JavaScriptが主流ですから。

つまり、ユーザーのデータを暗号したところ安全ではなく、実はパスワード(暗号キー)がバレバレであることを注意していただきたいです!

じゃあ、なんで暗号化なんかするんだ?!というと、周知の通り、暗号化と言っても、どこまでやれば本当に安全であるかの話になればキリがないので、ここの暗号化によって、そう簡単にチートされることはないだろうと、平文保存よりは多少マシであるだろうとのことが言えると思います。
実際の案件は暗号化の実装難易度や暗号/復号による負荷などでやり方が決まると思いますので、この方法はサーバーを介さず、手軽でやれるところがいいと思います。

何か誤りや質問があれば、お気軽にコメントください!^^b

参考:
  1. User Data Storage
  2. encryptjs
  3. How to install NodeJS and NPM on Mac using Homebrew
  4. How to import js-modules into TypeScript file?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください