Salam.
Ora suwe, nalika aku sinau ing universitas, ana kursus ing disiplin "Metode piranti lunak keamanan informasi." Tugas kasebut mbutuhake kita nggawe program sing ngemot pesen ing file GIF. Aku mutusaké kanggo nindakake ing Jawa.
Ing artikel iki aku bakal njlèntrèhaké sawetara TCTerms teori, uga carane program cilik iki digawe.
Bagean teoritis
format GIF
GIF (Graphics Interchange Format - format kanggo ijol-ijolan gambar) minangka format kanggo nyimpen gambar grafis, sing bisa nyimpen data sing dikompres tanpa mundhut kualitas ing format nganti 256 warna. Format iki dikembangake ing taun 1987 (GIF87a) dening CompuServe kanggo ngirim gambar raster liwat jaringan. Ing taun 1989, format kasebut diowahi (GIF89a), dhukungan kanggo transparansi lan animasi ditambahake.
File GIF duwe struktur blok. Pamblokiran iki tansah dawa tetep (utawa gumantung ing sawetara gendera), supaya iku meh mokal kanggo nggawe kesalahan ing ngendi saben blok dumunung. Struktur gambar GIF non-animasi paling gampang ing format GIF89a:
Kabeh blok struktur, ing kasus iki, kita bakal kasengsem ing blok palet global lan paramèter sing tanggung jawab kanggo palet:
CT - ngarsane palet global. Yen gendera iki disetel, palet global kudu diwiwiti sanalika sawise gagang layar logis.
Size - ukuran palet lan jumlah warna ing gambar. Nilai kanggo parameter iki:
Size
Jumlah werna
Ukuran palet, bita
7
256
768
6
128
384
5
64
192
4
32
96
3
16
48
2
8
24
1
4
12
0
2
6
Cara enkripsi
Cara ing ngisor iki bakal digunakake kanggo ndhelik pesen ing file gambar:
Metode LSB (Least Significant Bit).
Metode tambahan palet
metode LSB - cara umum steganography. Iku kasusun saka ngganti bit pinunjul pungkasan ing wadhah (ing kasus kita, bait palet global) karo bit saka pesen didhelikake.
Program kasebut bakal nggunakake rong bit pungkasan ing bait palet global minangka bagéan saka metode iki. Iki tegese kanggo gambar 24-bit, ing ngendi palet warna telung bita kanggo abang, biru, lan ijo, sawise nglebokake pesen, saben komponen warna bakal diganti kanthi maksimal gradasi 3/255. Owah-owahan kasebut, sepisanan, bakal ora katon utawa angel digatekake ing mripat manungsa, lan nomer loro, ora bakal katon ing piranti output informasi sing berkualitas rendah.
Jumlah informasi langsung gumantung saka ukuran palet gambar. Amarga ukuran maksimal palet yaiku 256 warna, lan yen rong bit pesen ditulis ing komponen saben warna, dawa pesen maksimal (kanthi palet maksimal ing gambar) yaiku 192 bita. Sawise pesen ditempelake ing gambar, ukuran file ora owah.
Metode ekspansi palet, sing mung dianggo kanggo struktur GIF. Bakal paling efektif ing gambar kanthi palet cilik. Intine yaiku nambah ukuran palet, saéngga nyedhiyakake papan tambahan kanggo nulis bait sing dibutuhake kanggo ngganti bait warna. Yen kita nganggep ukuran minimal palet yaiku 2 warna (6 bait), banjur ukuran maksimal pesen sing ditempelake bisa 256 × 3–6 = 762 bait. Kerugian kasebut yaiku keamanan kriptografi sing sithik; pesen sing dipasang bisa diwaca nggunakake editor teks apa wae yen pesen kasebut durung ngalami enkripsi tambahan.
Bagean praktis
Rancangan program
Kabeh alat sing dibutuhake kanggo ngetrapake algoritma enkripsi lan dekripsi bakal kalebu ing paket kasebut com.tsarik.steganography. Paket iki kalebu antarmuka Encryptor kanthi cara encrypt и decrypt, Kelas Binary, sing nyedhiyakake kemampuan kanggo nggarap susunan bit, uga kelas pengecualian UnableToEncryptException и UnableToDecryptException, sing kudu digunakake ing metode antarmuka Encryptor yen ana kesalahan enkoding lan dekoding.
Paket program utama com.tsarik.programs.gifed bakal kalebu kelas program runnable karo cara statis main, ngijini sampeyan kanggo mbukak program; kelas sing nyimpen paramèter program; lan paket karo kelas liyane.
Implementasi algoritma kasebut dhewe bakal ditampilake ing paket kasebut com.tsarik.programs.gifed.gif kelas GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Loro-lorone kelas kasebut bakal ngetrapake antarmuka Encryptor.
Adhedhasar struktur format GIF, sampeyan bisa nggawe algoritma umum kanggo ngenalake pesen menyang palet gambar:
Kanggo nemtokake anané pesen ing gambar, perlu kanggo nambah urutan bit tartamtu menyang wiwitan pesen, sing decoder maca pisanan lan mriksa bener. Yen ora cocog, mula dianggep ora ana pesen sing didhelikake ing gambar kasebut. Sabanjure sampeyan kudu nemtokake dawa pesen. Banjur teks pesen kasebut dhewe.
Diagram kelas saka kabeh aplikasi:
Implementasi program
Implementasine kabeh program bisa dipérang dadi rong komponen: implementasi enkripsi antarmuka lan metode dekripsi Encryptor, ing kelas GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, lan implementasine antarmuka panganggo.
Coba kelas GIFEncryptorByLSBMethod.
kothak firstLSBit и secondLSBit ngemot nomer bit saben bait gambar sing kudu dilebokake pesen lan saka ngendi pesen kasebut kudu diwaca. lapangan checkSequence nyimpen urutan dicokot mriksa kanggo mesthekake pangenalan pesen ditempelake. Metode statis getEncryptingFileParameters ngasilake paramèter file sing ditemtokake lan karakteristik pesen potensial.
Algoritma metode encrypt kelas GIFEncryptorByLSBMethod:
Lan kode dheweke:
@Override
public void encrypt(File in, File out, String text) throws UnableToEncodeException, NullPointerException, IOException {
if (in == null) {
throw new NullPointerException("Input file is null");
}
if (out == null) {
throw new NullPointerException("Output file is null");
}
if (text == null) {
throw new NullPointerException("Text is null");
}
// read bytes from input file
byte[] bytes = new byte[(int)in.length()];
InputStream is = new FileInputStream(in);
is.read(bytes);
is.close();
// check format
if (!(new String(bytes, 0, 6)).equals("GIF89a")) {
throw new UnableToEncodeException("Input file has wrong GIF format");
}
// read palette size property from first three bits in the 10-th byte from the file
byte[] b10 = Binary.toBitArray(bytes[10]);
byte bsize = Binary.toByte(new byte[] {b10[0], b10[1], b10[2]});
// calculate color count and possible message length
int bOrigColorCount = (int)Math.pow(2, bsize+1);
int possibleMessageLength = bOrigColorCount*3/4;
int possibleTextLength = possibleMessageLength-2;// one byte for check and one byte for message length
if (possibleTextLength < text.length()) {
throw new UnableToEncodeException("Text is too big");
}
int n = 13;
// write check sequence
for (int i = 0; i < checkSequence.length/2; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = checkSequence[2*i];
ba[secondLSBit] = checkSequence[2*i+1];
bytes[n] = Binary.toByte(ba);
n++;
}
// write text length
byte[] cl = Binary.toBitArray((byte)text.length());
for (int i = 0; i < cl.length/2; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = cl[2*i];
ba[secondLSBit] = cl[2*i+1];
bytes[n] = Binary.toByte(ba);
n++;
}
// write message
byte[] textBytes = text.getBytes();
for (int i = 0; i < textBytes.length; i++) {
byte[] c = Binary.toBitArray(textBytes[i]);
for (int ci = 0; ci < c.length/2; ci++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = c[2*ci];
ba[secondLSBit] = c[2*ci+1];
bytes[n] = Binary.toByte(ba);
n++;
}
}
// write output file
OutputStream os = new FileOutputStream(out);
os.write(bytes);
os.close();
}
Algoritma lan kode sumber metode decrypt kelas GIFEncryptorByLSBMethod:
@Override
public String decrypt(File in) throws UnableToDecodeException, NullPointerException, IOException {
if (in == null) {
throw new NullPointerException("Input file is null");
}
// read bytes from input file
byte[] bytes = new byte[(int)in.length()];
InputStream is = new FileInputStream(in);
is.read(bytes);
is.close();
// check format
if (!(new String(bytes, 0, 6)).equals("GIF89a")) {
throw new UnableToDecodeException("Input file has wrong GIF format");
}
// read palette size property from first three bits in the 10-th byte from the file
byte[] b10 = Binary.toBitArray(bytes[10]);
byte bsize = Binary.toByte(new byte[] {b10[0], b10[1], b10[2]});
// calculate color count and possible message length
int bOrigColorCount = (int)Math.pow(2, bsize+1);
int possibleMessageLength = bOrigColorCount*3/4;
int possibleTextLength = possibleMessageLength-2; // one byte for check and one byte for message length
int n = 13;
// read check sequence
byte[] csBits = new byte[checkSequence.length];
for (int i = 0; i < 4; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
csBits[2*i] = ba[firstLSBit];
csBits[2*i+1] = ba[secondLSBit];
n++;
}
byte cs = Binary.toByte(csBits);
if (cs != Binary.toByte(checkSequence)) {
throw new UnableToDecodeException("There is no encrypted message in the image (Check sequence is incorrect)");
}
// read text length
byte[] cl = new byte[8];
for (int i = 0; i < 4; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
cl[2*i] = ba[firstLSBit];
cl[2*i+1] = ba[secondLSBit];
n++;
}
byte textLength = Binary.toByte(cl);
if (textLength < 0) {
throw new UnableToDecodeException("Decoded text length is less than 0");
}
if (possibleTextLength < textLength) {
throw new UnableToDecodeException("There is no messages (Decoded message length (" + textLength + ") is less than Possible message length (" + possibleTextLength + "))");
}
// read text bits and make text bytes
byte[] bt = new byte[textLength];
for (int i = 0; i < bt.length; i++) {
byte[] bc = new byte[8];
for (int bci = 0; bci < bc.length/2; bci++) {
byte[] ba = Binary.toBitArray(bytes[n]);
bc[2*bci] = ba[firstLSBit];
bc[2*bci+1] = ba[secondLSBit];
n++;
}
bt[i] = Binary.toByte(bc);
}
return new String(bt);
}
Implementasi kelas GIFEncryptorByPaletteExtensionMethod bakal padha, mung cara nyimpen / maca informasi sing beda.
Ing kelas MainFrame cara pambungkus diterangake: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), ngolah asil metode antarmuka Encryptor lan sesambungan karo pangguna, yaiku mbukak dialog pilihan file, nuduhake pesen kesalahan, lsp; uga cara liyane: openImage(), ngidini pangguna milih gambar, exit(), sing metu saka aplikasi. Cara kasebut diarani saka Actionitem menu sing cocog. Kelas iki uga ngetrapake metode tambahan: createComponents() - nggawe komponen formulir, loadImageFile(File f) - ngemot gambar menyang komponen khusus saka file. Implementasi kelas GIFEncryptorByPaletteExtensionMethod padha karo implementasine kelas GIFEncryptorByLSBMethod, prabédan utama ing cara bait pesen ditulis lan diwaca saka palet.
Operasi program
metode LBS
Ayo kita ngomong yen ana gambar kaya iki:
Ing gambar iki, palet kasusun saka 256 werna (minangka Paint nyimpen). Papat werna pisanan yaiku: putih, ireng, abang, ijo. Werna liyane ireng. Urutan bit palet global bakal kaya ing ngisor iki: