Steganography mu GIF

Mau oyamba

Moni.
Osati kale kwambiri, pamene ndinali kuphunzira ku yunivesite, panali maphunziro mu chilango "Mapulogalamu njira chitetezo chidziwitso." Ntchitoyi idafuna kuti tipange pulogalamu yomwe imayika uthenga m'mafayilo a GIF. Ndinaganiza zochitira ku Java.

M'nkhaniyi ndikufotokozera mfundo zina zamaganizo, komanso momwe pulogalamu yaying'onoyi inapangidwira.

Theoretical gawo

Mtundu wa GIF

GIF (Graphics Interchange Format - mawonekedwe osinthira zithunzi) ndi mtundu wosungira zithunzi zojambulidwa, zomwe zimatha kusunga deta yoponderezedwa popanda kutayika kwamtundu wamitundu mpaka 256. Mtunduwu udapangidwa mu 1987 (GIF87a) ndi CompuServe potumiza zithunzi za raster pamanetiweki. Mu 1989, mawonekedwe adasinthidwa (GIF89a), kuthandizira powonekera ndi makanema adawonjezedwa.

Mafayilo a GIF ali ndi mawonekedwe a block. Mipiringidzo iyi nthawi zonse imakhala ndi utali wokhazikika (kapena zimatengera mbendera zina), kotero ndizosatheka kulakwitsa pomwe chipika chilichonse chili. Kapangidwe ka chithunzi chosavuta kwambiri cha GIF chosasinthika mumtundu wa GIF89a:

Steganography mu GIF

Pa midadada yonse ya kapangidwe kake, pakadali pano tikhala ndi chidwi ndi chipika chapadziko lonse lapansi ndi magawo omwe ali ndi phale:

  • CT - kukhalapo kwa phale lapadziko lonse lapansi. Ngati mbendera iyi yayikidwa, phale lapadziko lonse lapansi liyenera kuyamba pomwe chogwirizira chazenera chomveka.
  • Size - kukula kwa phale ndi kuchuluka kwa mitundu pachithunzichi. Makhalidwe a parameter iyi:

kukula
Chiwerengero cha mitundu
Palette kukula, mabayiti

7
256
768

6
128
384

5
64
192

4
32
96

3
16
48

2
8
24

1
4
12

0
2
6

Njira zolembera

Njira zotsatirazi zidzagwiritsidwa ntchito kubisa mauthenga mu mafayilo azithunzi:

  • Njira ya LSB (Yochepa Kwambiri).
  • Njira yowonjezera palette

Njira ya LSB - njira yodziwika bwino ya steganography. Zimapangidwa ndikusintha ma bits omaliza mu chidebe (kwa ife, ma byte apadziko lonse lapansi) ndi tizigawo ta uthenga wobisika.

Pulogalamuyi idzagwiritsa ntchito ma bits awiri omaliza mu ma byte apadziko lonse lapansi monga gawo la njirayi. Izi zikutanthauza kuti pa chithunzi cha 24-bit, pomwe phale lamtundu ndi ma byte atatu ofiira, abuluu, ndi obiriwira, mutatha kuyikamo uthenga, chigawo chilichonse chamtundu chidzasintha ndi kuchuluka kwa 3/255. Kusintha kotereku, choyamba, kudzakhala kosawoneka kapena kovuta kuzindikira ndi maso a munthu, ndipo kachiwiri, sikudzawoneka pazida zotulutsa chidziwitso chochepa.

Kuchuluka kwa chidziwitso kudzadalira mwachindunji kukula kwa phale la fano. Popeza kukula kwakukulu kwa phale ndi mitundu 256, ndipo ngati ma bits awiri a mauthenga alembedwa mu chigawo cha mtundu uliwonse, ndiye kuti kutalika kwa uthenga (ndi phale lapamwamba pachithunzi) ndi 192 bytes. Uthengawo ukayikidwa mu chithunzi, kukula kwa fayilo sikusintha.

Njira yowonjezera palette, zomwe zimangogwira ntchito pamapangidwe a GIF. Zidzakhala zogwira mtima kwambiri pazithunzi zokhala ndi phale laling'ono. Chofunikira chake ndikuti chimawonjezera kukula kwa phale, potero kupereka malo owonjezera olembera ma byte ofunikira m'malo mwa ma byte amtundu. Ngati tilingalira kuti kukula kochepa kwa phale ndi 2 mitundu (6 byte), ndiye kuti kukula kwakukulu kwa uthenga wophatikizidwa kungakhale 256 Γ— 3-6 = 762 bytes. Choyipa ndi chitetezo chochepa cha cryptographic; uthenga wophatikizidwa ukhoza kuwerengedwa pogwiritsa ntchito mkonzi uliwonse ngati uthengawo sunasinthidwenso.

Gawo lothandiza

Mapangidwe a pulogalamu

Zida zonse zofunika pakukhazikitsa ma encryption ndi decryption algorithms zidzaphatikizidwa mu phukusi com.tsarik.steganography. Phukusili lili ndi mawonekedwe Encryptor ndi njira encrypt ΠΈ decrypt, Kalasi Binary, yomwe imapereka kuthekera kogwira ntchito ndi magawo ang'onoang'ono, komanso makalasi apadera UnableToEncryptException ΠΈ UnableToDecryptException, zomwe ziyenera kugwiritsidwa ntchito mu njira zowonetsera Encryptor pakachitika zolakwika za encoding ndi decoding motsatana.

Main pulogalamu phukusi com.tsarik.programs.gifed idzaphatikizapo kalasi yothamanga yothamanga ndi njira yokhazikika main, kukulolani kuyendetsa pulogalamu; kalasi yomwe imasunga magawo a pulogalamu; ndi phukusi ndi makalasi ena.

Kukhazikitsidwa kwa ma algorithms okha kudzawonetsedwa mu phukusi com.tsarik.programs.gifed.gif makalasi GIFEncryptorByLSBMethod ΠΈ GIFEncryptorByPaletteExtensionMethod. Magulu awiriwa adzagwiritsa ntchito mawonekedwe Encryptor.

Kutengera mawonekedwe amtundu wa GIF, mutha kupanga algorithm wamba kuti mulowetse uthenga mupaleti yazithunzi:

Steganography mu GIF

Kuti mudziwe kupezeka kwa uthenga mu chithunzi, m'pofunika kuwonjezera ndondomeko zina za bits kumayambiriro kwa uthenga, zomwe decoder imawerenga poyamba ndikuyang'ana kulondola. Ngati sizikufanana, ndiye kuti zimaganiziridwa kuti palibe uthenga wobisika pachithunzichi. Kenako muyenera kufotokoza kutalika kwa uthengawo. Kenako lemba la uthengawo.

Chiwonetsero cha kalasi ya pulogalamu yonse:

Steganography mu GIF

Kukhazikitsa pulogalamu

Kukhazikitsidwa kwa pulogalamu yonseyo kutha kugawidwa m'zigawo ziwiri: kukhazikitsa mawonekedwe achinsinsi komanso njira zochepetsera Encryptor, m'makalasi GIFEncryptorByLSBMethod ΠΈ GIFEncryptorByPaletteExtensionMethod, ndi kukhazikitsidwa kwa mawonekedwe ogwiritsira ntchito.

Lingalirani za kalasi GIFEncryptorByLSBMethod.

Steganography mu GIF

m'minda firstLSBit ΠΈ secondLSBit muli ndi manambala a bits a byte iliyonse ya chithunzi chomwe uthenga uyenera kulowamo komanso komwe uthengawo uyenera kuwerengedwa. Munda checkSequence imasunga cheke kuti zitsimikizire kuzindikira kwa uthenga wophatikizidwa. Njira yosasunthika getEncryptingFileParameters imabweretsanso magawo a fayilo yotchulidwa ndi mawonekedwe a uthenga womwe ungakhalepo.

Njira algorithm encrypt kalasi GIFEncryptorByLSBMethod:

Steganography mu GIF

Ndipo kodi yake:

@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();
}

Algorithm ndi source code ya njira decrypt kalasi GIFEncryptorByLSBMethod:

Steganography mu 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);
}

Kukhazikitsa kalasi GIFEncryptorByPaletteExtensionMethod zidzakhala zofanana, njira yokhayo yosungira / yowerengera zambiri ndiyosiyana.

M'kalasi MainFrame Njira zopangira mapepala zimafotokozedwa: encryptImage(Encryptor encryptor) ΠΈ decryptImage(Encryptor encryptor), kukonza zotsatira za njira zowonetsera Encryptor ndi kuyanjana ndi wogwiritsa ntchito, mwachitsanzo, kutsegula bokosi losankha mafayilo, kusonyeza mauthenga olakwika, ndi zina zotero; komanso njira zina: openImage(), kulola wogwiritsa kusankha chithunzi, exit(), yomwe imatuluka. Njira izi zimatchedwa kuchokera Actionzinthu zofananira menyu. Gululi limagwiritsanso ntchito njira zothandizira: createComponents() - kupanga magawo a fomu, loadImageFile(File f) - kukweza chithunzi mu gawo lapadera kuchokera pafayilo. Kukhazikitsa kalasi GIFEncryptorByPaletteExtensionMethod zofanana ndi kukhazikitsa magalasi GIFEncryptorByLSBMethod, kusiyana kwakukulu ndi momwe ma byte a mauthenga amalembedwera ndi kuwerengedwa kuchokera pa phale.

Ntchito ya pulogalamu

Njira ya LBS

Tiyerekeze kuti pali chithunzi chonga ichi:

Steganography mu GIF

Pachithunzichi, phale lili ndi mitundu 256 (monga Paint imasungira). Mitundu inayi yoyamba ndi: yoyera, yakuda, yofiira, yobiriwira. Mitundu ina ndi yakuda. Kutsatizana kwapalette yapadziko lonse lapansi kudzakhala motere:

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

Steganography mu GIF

Uthengawo ukangophatikizidwa, ma bits omwe ali pansi adzasinthidwa ndi ma bits a uthengawo. Chithunzi chotsatira sichimasiyana ndi choyambirira.

Zachiyambi
Chithunzi chokhala ndi uthenga wophatikizidwa

Steganography mu GIF
Steganography mu GIF

Njira yowonjezera palette

Mukatsegula chithunzi chokhala ndi uthenga pogwiritsa ntchito njirayi, mudzawona chithunzi chotsatirachi:

Steganography mu GIF

N'zoonekeratu kuti njira si ntchito zonse ukazitape ntchito, ndipo angafunike zina kubisa uthenga.

Kubisa / kubisa muzithunzi zamakanema kumagwira ntchito ngati zithunzi zosasunthika, koma makanema ojambula samasweka.

Malo omwe amagwiritsidwa ntchito:

Koperani:

Source: www.habr.com

Kuwonjezera ndemanga