unity にも慣れ、「いざ、ストアにアップするような製品を作ろう!」となり、データ改ざんについても考えるようになると、かなり意識が高い(か、過去にひどい目になった経験がある)と言えますね。
今回は、データ初心者からの段階的な進歩過程を考えつつ、最終的に AES でデータをガッチガチに暗号化するサンプルコードを紹介します。
データについて考え始めた人にとって、お役に立てば幸いです。
なにも考えてない json
なにも考えてないんだから json でデータ取っておいたりします。
腹立つほど簡単にデータの中身が覗かれてしまいます。
まずいですよね。
これはただのサンプルデータなので意味はありませんが、普通にパスワードとか抜かれちゃう感じです。
「これが大企業 S〇NY もやっていた、平文管理だ!」と声を大きくしたところで、お叱りを受けるのは時間の問題。
誰かが見てみよう、そう思ったら終わりですから。
売り上げ数万本程度のゲームであれば、全然こんな感じでデータ保存してる事も多いです。
実際にデータを「見てみよう」と思う人は意外と少ないです。
とはいえ、万が一その情報をネット上にリークされると…。
そうだ、バイナリにしよう
save.bin みたいなバイナリデータにすれば、テキストエディタでは見えないでしょ!
json のテキストをバイナリ化してみます。
一歩進みましたね。
確かにこれで、一般人にはまずわからないデータになりました。
ところがこの数字、意味のわかる人にとってはなんの苦もなくデータが見えてしまいます。
右欄は、左欄の数字を解析し、文字に変換したものです。
たしかにテキストのようにそのままコピペできるわけではありませんが、データがそのまま丸見えなのがわかるでしょうか。
メモ帳ではこんな表示は不可能ですが、無料のテキストエディタやバイナリエディタでこれを行うことが可能です。
ファイルを圧縮すれば、ばれないんじゃね?
これでおそらく 99.9% の人にはわからないでしょう! 刑事事件の有罪判決並み!
個人のオフラインゲームなら、もうこのレベルまでで大きな問題は出ないかもしれません。
ですがガチャゲーなど分母の大きなゲームの場合、プレイ人口 100 万人 * 0.1% = 1000 人くらいこのデータを見破り、zip 解凍を試したりしちゃって、データを解読してしまうでしょう。
人気が高い、母数が大きいというのはそういうリスクを抱えているわけです。
そんなわけで暗号化
99.9% を 99.99999999% くらいにしたい。
というわけで暗号化の出番です。
素人目にパッと見ただけではもう圧縮かけたファイルと全然見分けつきませんが、先ほど圧縮したファイルに AES 暗号化を施しています。
これを解凍するのはもう国家を前にして日夜ハッキングに勤しんでいる人くらいです。
いちゲーム、いちアプリのためにそれをするのはハッキリ言って不毛です。
暗号化サンプル
Encrypt ボタンを押すと、暗号化したファイル Results/final_encrypt.bin を生成します。
Decrypt ボタンを押すと、final_encrypt.bin を複合化し、クラスデータに戻します。
詳しくは Sample.cs をご覧ください。
Aes 暗号で必要なキー
AesCbc.cs 複合化に必要なキーは2つ(SALT、IV)です。アプリパスワードから SALT、IV をランダム生成しています。
サーバー保存式のデータであれば、暗号化したデータと SALT、IV の保存先を変えるなどしてよりセキュリティリスクを高められますが、オフラインデータの場合はどこかにアプリパスワード、SALT、IV を隠しておく必要があります。
今回はサンプルなのでアプリパスワードはコードの中、SALT は暗号化データの先頭、IV は終端に入れてありますが、より安全性を高めることが出来るよう改良してみてください。
暗号化する前に、圧縮をかけるとベター
データサイズは小さいにこしたことはありません。テキストデータであれば圧縮をかけておくとよいでしょう。
この時気をつけるべき点は「暗号化した後ではなく、前に圧縮をかける」ということです。
暗号化した後は無規則なランダムデータとなり、ほぼ圧縮が効かなくなります。(むしろサイズが大きくなったりします)
圧縮する場合は、必ず暗号化する前にしましょう。
ただし、圧縮も暗号化も、どちらも処理時間はかかります。
頻繁に行うと UX を損なう恐れがあるので、使用タイミングは十分考慮しましょう。