〜 テキスト 〜
解析対策向けのビット演算による暗号化

使用データをファイル保存のやり方自体についてはコチラで別途説明するとして、
設定されたオプション等のデータを次回にも読み込んで使用する場合は、
利用者のいいようにデータを変更されると都合が悪く、開発側としてはデータ操作されることを嫌います。
そこで、簡単には解析されないようにデータを暗号化することが回避策として考えられます。
コチラコチラに載せてある暗号化を行うことで一目ではわからない文字列にすることができますが、
元データが英数字(半角文字)の場合、例えば「123」をビット加算して「STU」と暗号化したとしましょう。
すると、「コードの並びからしてココは『123』か?『3』が『U』ってことは『4』『V』になるな」と、
感のイイ人に解析されて、イイように改ざんされるかもしれません。
簡単に解析される要因として、全ての文字に対して一定の処理を加えている事が挙げられるでしょう。
一文字だけでは何がどう変わったのかわからなくても複数文字を互いに見比べるていると、
何らかの法則が見えてくるかもしれませんし、同じ文字位置のコード変化を監視することによって、
どこで使われているパラメータ値かを推測されてしまうかもしれません。
そこで、今回は一手間加えて、より解析されにくくする方法例を挙げておきましょう。
例えば、文字位置毎に処理する暗号化キーを変更することで、
ほとんど同じ数値が保存される初期の状態でも、同一値が保存されているように見えなくなるでしょう。
他に、保存の度にキーを変更して、前回保存時と同じ値であっても別のコードとなるように処理すれば、
どこで使われているどんな値かを見破られにくくなることでしょう。
また、データ不正改ざん対策のチェックサムを設けることで、改ざんテストを防止することも出来ます。
さて、具体的に「どう処理するか」ですが、偶数文字位置・奇数文字位置毎にキーを変更したり、
キーに乱数を利用したり、ファイル保存時の更新日時をキーに利用するなどいろいろありますね。
下記サンプルでは、乱数パターンを利用したビット反転モジュールです。
グローバル領域で不定値を取る乱数の初期化を行ってるので、実行の度に異なるコードとなりますが、
起動している状態で再度モジュール命令を実行しても、前回と同じコードパターンとなりますので、
きちんと復号化できるようになっているのです。
いつかに保存したデータを読み込む時には、保存した時の乱数パターンも同時に読み込んでやりましょう。
補足ですが、内部で固定の乱数を発生させる初期化を行ってますので、
モジュール命令使用後にグローバル領域で乱数を取得する場合は、再度randomize命令を実行してください。
	

encrypt 変数, キー
変数暗号化するテキストの入った文字列型変数を指定する。
キー暗号化に使用するキーを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#module
#deffunc encrypt val, int
	mref s, 24 : mref key, 1
	randomize key                             // 一定パターンで乱数発生
	strlen len, s
	repeat len
		peek code, s, cnt
		rnd r, 256
		code = code ^ r
		if code = 0 : continue
		poke s, cnt, code
	loop
	return
#global

	randomize
	rnd enckey, 32768
	mes "乱数初期化キー:" + enckey
	string = "000000000000000000000000000000" // わかりやすいようにあえて同じ文字のみを暗号化する
	mes "元の文字列:  " + string
	encrypt string, enckey                    // 暗号化
	mes "暗号化文字列: " + string
	encrypt string, enckey                    // 復号化
	mes "復号化文字列: " + string
	stop

encrypt 変数, キー
変数暗号化するテキストの入った文字列型変数を指定する。
キー暗号化に使用するキーを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#module
#deffunc encrypt var s, int key, local code
	randomize key                             // 一定パターンで乱数発生
	repeat strlen(s)
		code = peek(s, cnt) ^ rnd(256)
		if code = 0 : continue
		poke s, cnt, code
	loop
	return
#global

	randomize
	enckey = rnd(32768)
	mes "乱数初期化キー:" + enckey
	string = "000000000000000000000000000000" // わかりやすいようにあえて同じ文字のみを暗号化する
	mes "元の文字列:  " + string
	encrypt string, enckey                    // 暗号化
	mes "暗号化文字列: " + string
	encrypt string, enckey                    // 復号化
	mes "復号化文字列: " + string