どうも,hide92795です
夏休みの補習っていうのがね(´・ω・`)
ホント辛いですよw
今回はノベルゲームのエンジンに搭載予定の暗号化システムについて
使用する暗号化方式はAES、モードはPCBCです。
PCBCというわけで、復号化の際にはIVというのが必要になります。
IVは暗号化の際に取得できるのでそれをどうにか復号化の際に使える状態にしなければいけないのですが、
今回はこちらのサイトにて紹介されている方法である
「ファイルの先頭にIVを引っ付ける」
という方法で行きたいと思います。
まずは暗号化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
FileInputStream fis = new FileInputStream(src); Key key = new SecretKeySpec("0123456789ABCDEF".getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/PCBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); FileOutputStream fos = new FileOutputStream("hoge.hoge"); CipherOutputStream cos = new CipherOutputStream(fos, cipher); fos.write(cipher.getIV()); byte[] a = new byte[8]; int i = fis.read(a); while (i != -1) { cos.write(a, 0, i); i = fis.read(a); } cos.flush(); cos.close(); |
上から順に解説すると
1.暗号化するファイルのFileInputStreamを生成
2.暗号化に用いるKeyを作成(鍵は16文字のStringみたいです)
3.AES/PCBC/PKCS5PaddingにてChiperを作成&初期化
4.出力先のFileOutputStreamを作成
5.↑をCipherOutputStreamで包む
6.FileOutputStreamにIVを書き込む
7.CipherOutputStreamに暗号化するデータを書き込む
となります。
今回はIVを平文の状態で書かなければいけないのでFileOutputStreamの方に書き込みます。
続いて復号化
1 2 3 4 5 6 7 8 |
Key key = new SecretKeySpec("0123456789ABCDEF".getBytes(), "AES"); FileInputStream fis = new FileInputStream("hoge.hoge"); byte[] iv = new byte[16]; fis.read(iv); Cipher cipher = Cipher.getInstance("AES/PCBC/PKCS5Padding"); IvParameterSpec ivspec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, key, ivspec); CipherInputStream cis = new CipherInputStream(fis, cipher); |
こちらも上から順に
1.Keyの生成
2.暗号化したファイルのFileInputStreamの生成
3.IV用のbyte配列を作成
4.FileInputStreamからIV部分を3の配列に読み込み
5.Chiperを生成
6.4で読み込んだIVからIvParameterSpecを生成
7.6を使ってChiperを初期化
8.CipherInputStreamでFileInputStreamを包む
残りはChiperInputStreamで読みこむなりまた別のStreamに渡すなりしておkです
実際に暗号化してみたのが下の画像
左が暗号化前、右が暗号化後
JPEGなので左ではExif情報があらわになっていますが、右では全く読めなくなっていますw
ファイルサイズは殆ど変わらず、暗号化後が8バイト増えただけでした
ちなみに、ファイルを圧縮したい場合は、FileOutputStreamをZipOutputStreamで包んだ(new ZipOutputStream(fis)みたいに)ほうが圧縮率がいいらしいです。
ではノシ