hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。 |
シナリオデータや画像データのような中身を見られると困るものや、セーブデータやクリアスコアなど改ざんされると困るデータは、ゲームではそのままだとちょっと困りものです。 暗号化してこれらを防げないでしょうか。
ということで、暗号化について考えてみます。
文字列とは文字が複数連なった物の事。文字は A や あ といた1文字の事なので「ABCDE」や「あいうえお」が文字列という事になります。
コンピュータの内では全ての情報を数値として扱っているので、当然文字列も数値で扱われます。
例えばアスキー文字で 'A' なら数値で 65 として定義されてる。
文字コードにはいくつかの種類があり 文字の定義や1文字を何バイトで表すか等が異なる、HSPではマルチバイト文字という 1バイトのアスキー文字と 日本の文字を表現する2バイト文字が混在した 通称 Shift_JISが使われる。
詳しくは Google にて。
バイトというのは8ビットからなる0から255までの値で、暗号化では文字コードの数値にある一定の値を加算減算したり、XOR演算したりすることによってもともとの文字を出鱈目な言葉に変換します。
しかし、もしもアスキーコードで255の文字があったとすれば、その文字に+1加算させた暗号化をしようとすると、バイトというのは0~255までの値なので256になってしまってどうなるのだろうかと思うと思います。実際には、255に+1すると、0に戻るようになっています。逆に0に-1すると、255になるというようにできているわけです。具体的な仕組みは割合しますが、この仕組みを応用することでより幅の広い暗号化が実現できます。
暗号化を行うためには加算減算やXOR演算などでどの数値を利用すればいいのか予め決めておかなくてはなりません。しかし、もしもこの値が固定だとしたら格段と解読される確率が高くなってしまうため暗号化させる文章によって変化する不規則な数値が望ましいです。注意すべきところは、暗号化を行う文章と行った文章二つの中で共通して得られる数値であることだ。
- 暗号化を行う文章のサイズ値
- strlenで取得した暗号化を行うための文章のサイズ値。
- 鍵のサイズ値
- 鍵を利用する場合はそのサイズ値
- 鍵暗号
- 鍵というのは数値で、暗号文とは別に引数として受け渡す値です。文字列型の鍵もありますが、内部では数値に変換されるものがほとんどです。この数値を元に暗号化を行う。
またこの他にも数学的な値を利用することができる。
- 倍数
- 冪乗数
- 素数
また、繰り返し命令におけるcntを利用することもある。
- cnt
PACKFILEに入れるだけで、HSPが自動的に暗号化してくれます。
復号ツールがあるかもしれませんが、簡単に暗号化できるひとつの方法ではあります。何もしないよりは、はるかにましです。
問題点としてはデータの書き込みが出来ない。(出来てもむずかしい。)
暗号化強度を変えられない。などという点があります。
ではまずは基本的な暗号化の手順から。基本的な流れはこのサンプルと大きくは違わないと思います。
用意するものは、暗号化したい原文と、暗号化・複合化に使う暗号キー。
今回はXORを使用した簡単なサンプルを作ってみました。
+ | その1 |
|
このスクリプトで暗号化作業をしているのは、この1行。
buf = buf ^ rnd(200)
この行を工夫することで色んな暗号化を行うことが出来るようになります。
加算減算を利用して暗号化を行います。繰り返し命令のcntの値でXOR演算していますが、最終的にはその評価を加算減算しています。
+ | スクリプト |
|
暗号化は通常バイナリとして扱い,暗号化データのサイズを復号時に指定する必要がありますが,下記のようにヌル文字を処理することで,暗号化データのサイズを指定しないですむ方法もあります。
暗号化された文章に必然的に出てきてしまうのが0x00のヌル文字です。文字列の場合は、このヌル文字を終端としてここまでが文章だと認識します。暗号化された文章も文字列であるためこのヌル文字による文章の終了が起きてしまいます。
ヌル文字を使わなければいいのではないかとも思うかもしれませんが、絶対使わないというわけにはいきません。というのは、バイトの仕組みで述べたように255に1加算しただけでも0になってしまうので、いつなんどきヌル文字が発生するのかわからないためです。またXORも同様に”A=B”において”A^B”といった式があるとその評価は"0"となりヌル文字を発生させます。
このようにヌル文字は絶対出てしまうもので、幾つかの対策方法を記載します。
- ヌル文字を別の文字に置き換える
- ヌル文字が現れた箇所を、0xFFなどの全く関係のない文字に置き換えます。こうすれば、ヌル文字は取り除かれファイルの読み書きや変数から変数への受け渡しが行えるようになります。置き換えたバイト位置は暗号化文の終端に数値として保持しておきます。
- 一度も利用されていないアスキーコードで置き換える
- 暗号化の中でヌル文字の箇所を一度も利用されていない文字で置き換えます。暗号化文の最後にその文字を書き込み、復号するときにその文字を全てヌル文字に置き換えます。しかし欠点があり、一度も利用されていないアスキーコードがなかった場合は使用できません。
暗号は解読できるように作られたものなので、どんな強力な暗号化をしても時間さえかければ解けない暗号は存在しません。ポイントはいかに解読する気にさせないかです。
運用を誤らない限り第三者には絶対に復号不可能な暗号は理論上は存在します。例えば…解読には手間と時間がかかりますので、暗号化してあるデータの価値が解読する手間と時間にみあうだけのものでなければ誰も解読しようとしないでしょう。
あるいはデータをレジストリに隠すなどして一見みえなくすることで、「ちょっとチートしてみようかな?」という気軽な動機をおさえることも出来るかもしれません。
HSPで暗号化を扱う際には暗号化する前のデータや復号するために使用するキーを,リテラルとしてプログラム内に定義することは望ましくありません。
デコンパイルすることによって簡単にそれらのリテラルがばれてしまうためです。なので,プログラムで暗号化を用いる場合は,ユーザーにキーを指定してもらって暗号化を施す必要があるもの,例えば日記ソフトなどそういった部類のソフトウェアでしか応用が利かなくなります。
ゲームのセーブデータなどはプログラム内にキー情報を保持させるしか方法がないので,簡単に暴かれてしまうことになります。頑丈な暗号化を望むなら,外部プラグインを利用した方法がいいでしょう。