Steganografi ing GIF

Pambuka

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:

Steganografi ing GIF

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:

Steganografi ing GIF

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:

Steganografi ing GIF

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.

Steganografi ing GIF

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:

Steganografi ing GIF

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:

Steganografi ing GIF

@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:

Steganografi ing GIF

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:

11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000...

Steganografi ing GIF

Sawise pesen ditempelake, bit sing digaris ngisor bakal diganti karo bit saka pesen. Gambar sing diasilake meh ora beda karo asline.

Asli
Gambar kanthi pesen sing dipasang

Steganografi ing GIF
Steganografi ing GIF

Metode ekspansi palet

Nalika sampeyan mbukak gambar sing ngemot pesen nggunakake metode iki, sampeyan bakal weruh gambar ing ngisor iki:

Steganografi ing GIF

Cetha yen cara iki ora bisa digunakake kanggo aktivitas spionase lengkap, lan bisa uga mbutuhake enkripsi tambahan kanggo pesen kasebut.

Enkripsi/dekripsi ing gambar animasi dianggo kaya ing gambar statis biasa, nanging animasi ora rusak.

Sumber sing digunakake:

Unduh:

Source: www.habr.com

Add a comment