○パイプとリダイレクトを使いファイルの暗号化

■準備1
パイプとリダイレクトで1バイトデータ 0x00 から 0xFF の値が 全て受け渡しできる事を確認します。
まずは、0x0から0xFFまで出力するプログラムを作成

a.c
#include <stdio.h>

main(){
	int i;
	for(i=0;i<=0xFF;i++){
		fputc(i,stdout);
	}
}


▼上のプログラムから値を受け取るプログラム

test.c
#include <stdio.h>

main(){

	int c;
	FILE *fp;
	fp=stdin;
	while(EOF!=(c=fgetc(fp))){
		printf("%p\n",c);
	}
}


▼Linuxでのプログラムをコンパイルと実行結果
gcc -o a a.c
gcc -o test test.c


$ ./a | ./test
0x0
0x1
......省略.........
0xfe
0xff

0x00から0xFFまでが受け取れる事を確認できました Linuxでは大丈夫みたいです


▼Windows(Windows XP)での実行結果
C:\>a.exe | test.exe

00000000
00000001
......省略.........
00000018
00000019

0x1A から 0xFF までの値が受け取れないことが確認できました
Windowsでこの手のソフトは不可能みたいです Windowsではあきらめる事にします。


■準備2
1バイトデータ 0x00 から 0xFF の値が保存でき、それを読み出せる事を確認します

▼aの出力結果をファイルに保存する
test@Note2 ~
$ ./a > aaa

▼ファイルaaaの出力結果を表示
$ cat aaa
 
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~≠ヤ・炎旧克署葬灯楓利劒屆撼泛。「」、・ヲァィゥェォャュョッ
ーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・@・

▼保存したファイルの値を読み出し
$ cat aaa | ./test
0x0
0x1
......省略.........
0xfe
0xff
Linuxではファイルに保存され、それを呼び出せる事を確認できました


■暗号化ソフトの作成

暗号化を簡易的に行うために一文字ごとに XOR を取ることにします。
XORは二回繰り返すと自分の値に戻ってくるため、 その性質を利用して暗号化・複合化を行いたいと思います。
実際に暗号化するときは乱数などを使ってください。

test.c
#include <stdio.h>

main(){

	int c;
	FILE *fp;
	fp=stdin;
	while(EOF!=(c=fgetc(fp))){
		c=c^0x5A;//XORを取る
		fputc(c,stdout);
	}
}


■実行

▼暗号元になるファイルaaaを作成
$ ./a > aaa

$ cat aaa
 
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~≠ヤ・炎旧克署葬灯楓利劒屆撼泛。「」、・ヲァィゥェォャュョッ
ーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・@・

▼ファイルを暗号化してbbbに保存
$ cat aaa | ./test > bbb

▼bbbの内容を出力
$ cat bbb
Z[XY^_\]RSPQVWTUJKHINOLMBC@AFGDEz{xy~|}rspqvwtujkhinolmbc`afgde
	
 :;89>?<=23016745*+()./,-"# !&'$%レロリル゙゚ワンメモミムヨラヤユハヒネノホマフヘツテタチニヌトナ
・・韜@・粤珮跚蒟圀・棔悃駐髄沫舶葛・誌訣c≧пEサクケセソシスイウーアカキ
エオェォィゥョッャュ「」。ヲァ、・

▼bbbを復号化しファイル名cccに保存
$ cat bbb | ./test > ccc

$ cat ccc
 
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~≠ヤ・炎旧克署葬灯楓利劒屆撼泛。「」、・ヲァィゥェォャュョッ
ーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・@・
元のファイルと差分をとると同一の内容でした。
暗号化→複合化がきちんと動作している事が確認できました。


■先方作成した実行ファイル a.exe を暗号化→復号化して実行できるか確認してみます

▼a.exe を b.exe として保存
$ cat a.exe | ./test > b.exe

▼b.exe を c.exe として保存
$ cat b.exe | ./test > c.exe

▼実行権限を付加
$ chmod 777 c.exe

▼実行
$ ./c
$ cat ccc
 
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~≠ヤ・炎旧克署葬灯楓利劒屆撼泛。「」、・ヲァィゥェォャュョッ
ーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・@・
暗号化→複合化 された実行ファイルが実行できることが確認できました。
うまくいったみたいです
もちろん暗号化された b.exe をバイナリエディタで見るとめちゃめちゃになってます。


■まとめ

Windowsではパイプとリダイレクトにより全ての1バイトデータが受け渡しできないため この手のプログラムは作成できない事がわかりました。
Linuxではパイプとリダイレクトで0x00から0xFFまでの全ての値を渡すことができ、 簡単なプログラムで暗号化・複合化ができることがわかりました。


▲トップページ > プログラミングの実験