こんばんわ
ファイルを簡単に暗号化する方法を模索した時のメモです。
ふーんって程度に。
動機
平文はちょっとな~ってレベルのファイルを簡単に暗号化する方法を知りたかった。
見られるのは嫌だけどガチガチに暗号化するレベルのモノではないときに使いたい。
環境
Windows 10/11 (バージョン省略)
OpenSSL1.0.2
OpenSSL1.1.1
Git Bash
MSYS2
gcc or g++ or clang++
(Pythonとかなんでもいいです)
Linuxコマンド使えれば何でも良いです(多分)
サンプルファイル
今回はこれをなんちゃって暗号化とOpenSSLで暗号化してみる。
ファイル名はfile.txt
abcdefg fdadsafdsa abcdefg fdasdfghthtjhh tretafdsgdghs dssaweqt231551 gdhbdfst 351242 あいうえよんさ
最終的に3パターン考えましたが,
やっぱりOpenSSLが安定です。
1. xxdコマンドを駆使する
16進数や2進数でダンプするコマンド。
オプションr(-r, -revert)が16進ダンプをバイナリに変換するのでこれを利用する。
xxd file.txt > dump.txt
で16進数でダンプして
xxd -r dump.txt > origin.txt
で元に戻す。
1. xxd file.txt > dump.txt
dump.txtの中身はこれ
00000000: 6162 6364 6566 670a 6664 6164 7361 6664 abcdefg.fdadsafd 00000010: 7361 0a61 6263 6465 6667 0a66 6461 7364 sa.abcdefg.fdasd 00000020: 6667 6874 6874 6a68 680a 7472 6574 6166 fghthtjhh.tretaf 00000030: 6473 6764 6768 730a 6473 7361 7765 7174 dsgdghs.dssaweqt 00000040: 3233 3135 3531 0a67 6468 6264 6673 7420 231551.gdhbdfst 00000050: 3335 3132 3432 200a 351242 .
丸見えだけど,何回かxxd
すればわかんないんじゃね?
2. xxd file.txt | xxd > dump.txt
3回やったら長かったので,ここでは2回の結果で。
00000000: 3030 3030 3030 3030 3a20 3631 3632 2036 00000000: 6162 6 00000010: 3336 3420 3635 3636 2036 3730 6120 3636 364 6566 670a 66 00000020: 3634 2036 3136 3420 3733 3631 2036 3636 64 6164 7361 666 00000030: 3420 2061 6263 6465 6667 2e66 6461 6473 4 abcdefg.fdads 00000040: 6166 640a 3030 3030 3030 3130 3a20 3733 afd.00000010: 73 00000050: 3631 2030 6136 3120 3632 3633 2036 3436 61 0a61 6263 646 00000060: 3520 3636 3637 2030 6136 3620 3634 3631 5 6667 0a66 6461 00000070: 2037 3336 3420 2073 612e 6162 6364 6566 7364 sa.abcdef 00000080: 672e 6664 6173 640a 3030 3030 3030 3230 g.fdasd.00000020 00000090: 3a20 3636 3637 2036 3837 3420 3638 3734 : 6667 6874 6874 000000a0: 2036 6136 3820 3638 3061 2037 3437 3220 6a68 680a 7472 000000b0: 3635 3734 2036 3136 3620 2066 6768 7468 6574 6166 fghth 000000c0: 746a 6868 2e74 7265 7461 660a 3030 3030 tjhh.tretaf.0000 000000d0: 3030 3330 3a20 3634 3733 2036 3736 3420 0030: 6473 6764 000000e0: 3637 3638 2037 3330 6120 3634 3733 2037 6768 730a 6473 7 000000f0: 3336 3120 3737 3635 2037 3137 3420 2064 361 7765 7174 d 00000100: 7367 6467 6873 2e64 7373 6177 6571 740a sgdghs.dssaweqt. 00000110: 3030 3030 3030 3430 3a20 3332 3333 2033 00000040: 3233 3 00000120: 3133 3520 3335 3331 2030 6136 3720 3634 135 3531 0a67 64 00000130: 3638 2036 3236 3420 3636 3733 2037 3432 68 6264 6673 742 00000140: 3020 2032 3331 3535 312e 6764 6862 6466 0 231551.gdhbdf 00000150: 7374 200a 3030 3030 3030 3530 3a20 3333 st .00000050: 33 00000160: 3335 2033 3133 3220 3334 3332 2032 3030 35 3132 3432 200 00000170: 6120 6533 3831 2038 3265 3320 3831 3834 a e381 82e3 8184 00000180: 2065 3338 3120 2033 3531 3234 3220 2e2e e381 351242 .. 00000190: 2e2e 2e2e 2e2e 2e0a 3030 3030 3030 3630 ........00000060 000001a0: 3a20 3836 6533 2038 3138 3820 6533 3832 : 86e3 8188 e382 000001b0: 2038 3865 3320 3832 3933 2065 3338 3120 88e3 8293 e381 000001c0: 3935 3061 2020 2020 2020 202e 2e2e 2e2e 950a ..... 000001d0: 2e2e 2e2e 2e2e 2e2e 2e0a ..........
英数字はそのまんまだけど,1回だけよりはマシかな…
3. xxd -r dump.txt | xxd -r
問題なく元に戻る。
xxd
を行った回数xxd -r
すればよい。
わかりにくくなったし,日本語文章だけならxxd
を数回すれば自分的には十分かな。
ただxxd
の度にファイルサイズが増大すること,英数字にはほぼ無力。
あとxxd
コマンドを知っている人には直ぐバレるのが欠点。
オプションseek(-seek)とか,オプションを駆使すればわかりにくくはできると思う。
2. xxdコマンドからC/C++で読み込む
オプションi(-i, -include)でC言語形式のファイルを出力するので,これを利用する。
正直,プログラム書くならxor暗号で暗号化するプログラムを書いた方がマシ。
1. xxd -i file.txt > aiueo.data
こんな感じのが出力される。
unsigned char aiueo_txt[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x0a, 0x66, 0x64, 0x61, 0x64, 0x73, 0x61, 0x66, 0x64, 0x73, 0x61, 0x0a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x0a, 0x66, 0x64, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x74, 0x68, 0x74, 0x6a, 0x68, 0x68, 0x0a, 0x74, 0x72, 0x65, 0x74, 0x61, 0x66, 0x64, 0x73, 0x67, 0x64, 0x67, 0x68, 0x73, 0x0a, 0x64, 0x73, 0x73, 0x61, 0x77, 0x65, 0x71, 0x74, 0x32, 0x33, 0x31, 0x35, 0x35, 0x31, 0x0a, 0x67, 0x64, 0x68, 0x62, 0x64, 0x66, 0x73, 0x74, 0x20, 0x33, 0x35, 0x31, 0x32, 0x34, 0x32, 0x20, 0x0a, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x82, 0x88, 0xe3, 0x82, 0x93, 0xe3, 0x81, 0x95, 0x0a }; unsigned int aiueo_txt_len = 110;
雑に読むなら下のプログラムで十分なはず。
#include <iostream> #include "aiueo.data" int main() { for (int i = 0u; i < aiueo_txt_len; ++i) { std::cout << aiueo_txt[i]; } return 0; }
3. OpenSSLで暗号化
openssl
コマンドで暗号化できるらしいことを知りました。
この方法が最強だと思います。
openssl enc -e -aes128 -in file.txt -out dump.txt -pass pass:aiueo
openssl enc -e -aes128 -in file.txt -pass pass:aiueo > dump.txt
暗号化オプションを選択して入出力ファイルを指定し,パスワードを設定。
複合はオプションe(-e)をオプションd(-d)にすればよい。
openssl enc -d -aes128 -in file.txt -out dump.txt -pass pass:aiueo
多分どんなファイルでも大丈夫。
と思ったのですが,実際に使ってみたら上手くいきませんでした。
OpenSSL1.0.2で暗号化したものをOpenSSL1.1.1で複合したら失敗しました。
どうやらOpenSSLのバージョンが関係しているそうです
(運良く暗号側がOpenSSL1.0.2を使用してた)
OpenSSL1.1.0と以前のバージョンとの互換性
ArchLinuxのOpenSSLのページでも言及されてますね。
ダイジェストアルゴリズムを合わせれば問題なく読めました。
暗号と複合が逆なら合わせればおけー。
暗号側 OpenSSL1.0.2: MD5
openssl enc -e -aes128 -in file.txt -pass pass:aiueo > dump.txt
複合側 OpenSSL1.1.1: SHA256 -> MD5
openssl enc -d -aes128 -md md5 -in file.txt -out dump.txt -pass pass:aiueo
MD5の安全性が気になる人はSHA-256とか使うと良さそうです。
自分はそこまで気にしてないのでMD5でいいや。
まとめ
OpenSSLがさいつよだけど,バージョン互換には注意。
(OpenSSLは公式ではソースコードしか配布していないっぽい(?)ので,Msys2やWSL2の力を借りるのが早そう)
xxdで暗号化を考えるより「暗号化 コマンド」でググったらOpenSSLが出てきたのでGoogle検索は偉大。
初めからきちんと調べてから取り組みましょうって話だよね