Esteganografi nan GIF

Entwodiksyon

Bonjou.
Sa pa gen lontan, lè m t ap etidye nan inivèsite a, te gen yon kou nan disiplin "Metòd lojisyèl sekirite enfòmasyon." Devwa a te mande pou nou kreye yon pwogram ki entegre yon mesaj nan dosye GIF. Mwen deside fè li nan Java.

Nan atik sa a mwen pral dekri kèk pwen teyorik, osi byen ke kòman ti pwogram sa a te kreye.

Pati teyorik

Fòma GIF

GIF (Graphics Interchange Format - yon fòma pou echanj imaj) se yon fòma pou estoke imaj grafik, ki kapab estoke done konprese san pèt kalite nan yon fòma ki rive jiska 256 koulè. Fòma sa a te devlope an 1987 (GIF87a) pa CompuServe pou transmèt imaj raster sou rezo yo. An 1989, yo te modifye fòma a (GIF89a), yo te ajoute sipò pou transparans ak animasyon.

Fichye GIF gen yon estrikti blòk. Blòk sa yo toujou gen yon longè fiks (oswa sa depann de kèk drapo), kidonk li prèske enposib fè yon erè sou kote chak blòk ye. Estrikti imaj GIF ki pi senp ki pa anime nan fòma GIF89a:

Esteganografi nan GIF

Nan tout blòk yo nan estrikti a, nan ka sa a nou pral enterese nan blòk la palèt mondyal ak paramèt ki responsab pou palèt la:

  • CT - prezans nan yon palèt mondyal. Si yo mete drapo sa a, palèt mondyal la dwe kòmanse imedyatman apre manch ekran ki lojik la.
  • Size - gwosè palèt ak kantite koulè nan foto a. Valè pou paramèt sa a:

Kantite moun ki
Kantite koulè
Gwosè palèt, bytes

7
256
768

6
128
384

5
64
192

4
32
96

3
16
48

2
8
24

1
4
12

0
2
6

Metòd chifreman

Metòd sa yo pral itilize pou ankripte mesaj nan dosye imaj:

  • LSB (Least Siyifikatif Bit) metòd
  • Palèt adisyon metòd

Metòd LSB - yon metòd komen nan steganografi. Li konsiste de ranplase dènye Bits enpòtan nan veso a (nan ka nou an, bytes palèt mondyal yo) ak Bits yo nan mesaj la kache.

Pwogram nan pral sèvi ak de dènye bit yo nan bytes palèt mondyal yo kòm yon pati nan metòd sa a. Sa vle di ke pou yon imaj 24-bit, kote palèt koulè a ​​se twa byte pou wouj, ble, ak vèt, apre yo fin entegre yon mesaj nan li, chak eleman koulè pral chanje pa yon maksimòm de 3/255 gradyasyon. Chanjman sa a, premyèman, yo pral envizib oswa difisil pou remake nan je imen an, epi dezyèmman, li pa pral vizib sou aparèy pwodiksyon enfòmasyon ki ba-bon jan kalite.

Kantite enfòmasyon an pral dirèkteman depann sou gwosè a nan palèt imaj la. Depi gwosè maksimòm palèt la se 256 koulè, epi si yo ekri de moso mesaj nan eleman chak koulè, lè sa a longè maksimòm mesaj la (ak palèt maksimòm nan imaj la) se 192 octets. Yon fwa mesaj la entegre nan imaj la, gwosè dosye a pa chanje.

Metòd ekspansyon palèt, ki travay sèlman pou estrikti GIF la. Li pral pi efikas sou imaj ki gen yon ti palèt. Sans li se ke li ogmante gwosè a nan palèt la, kidonk bay plis espas pou ekri octets ki nesesè yo nan plas bytes koulè yo. Si nou konsidere ke gwosè minimòm palèt la se 2 koulè (6 octets), Lè sa a, gwosè maksimòm mesaj entegre a ka 256 × 3–6 = 762 bytes. Dezavantaj la se sekirite kriptografik ki ba; mesaj entegre a ka li lè l sèvi avèk nenpòt editè tèks si mesaj la pa te sibi chifreman adisyonèl.

Pati pratik

Konsepsyon pwogram lan

Tout zouti ki nesesè pou mete ann aplikasyon chifreman ak algoritm dechifre yo pral enkli nan pake a com.tsarik.steganography. Pake sa a gen ladan koòdone a Encryptor ak metòd encrypt и decrypt, Klas Binary, ki bay kapasite pou travay ak etalaj bit, osi byen ke klas eksepsyon UnableToEncryptException и UnableToDecryptException, ki ta dwe itilize nan metòd koòdone Encryptor an ka ta gen kodaj ak dekodaj erè respektivman.

Pake pwogram prensipal la com.tsarik.programs.gifed pral gen ladan yon klas pwogram ki ka kouri ak yon metòd estatik main, ki pèmèt ou kouri pwogram nan; yon klas ki estoke paramèt pwogram yo; ak pakè ak lòt klas.

Aplikasyon an nan algoritm yo tèt yo pral prezante nan pake a com.tsarik.programs.gifed.gif klas yo GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Tou de nan klas sa yo pral aplike koòdone a Encryptor.

Dapre estrikti fòma GIF a, ou ka kreye yon algorithm jeneral pou entwodwi yon mesaj nan palèt imaj la:

Esteganografi nan GIF

Pou detèmine prezans nan yon mesaj nan yon imaj, li nesesè ajoute yon sekans sèten nan Bits nan kòmansman an nan mesaj la, ki dekodè a li an premye epi tcheke pou kòrèk. Si li pa matche ak, Lè sa a, li konsidere ke pa gen okenn mesaj kache nan imaj la. Apre sa, ou bezwen presize longè mesaj la. Lè sa a, tèks mesaj la li menm.

Dyagram klas tout aplikasyon an:

Esteganografi nan GIF

Aplikasyon pwogram nan

Aplikasyon an nan pwogram nan tout antye ka divize an de eleman: aplikasyon an koòdone chifreman ak metòd dechifre Encryptor, nan klas yo GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, ak aplikasyon an nan koòdone itilizatè a.

Konsidere klas la GIFEncryptorByLSBMethod.

Esteganografi nan GIF

Jaden firstLSBit и secondLSBit gen nimewo yo nan bit nan chak byte nan imaj la nan ki mesaj la ta dwe antre epi ki soti nan kote yo ta dwe li mesaj la. Jaden checkSequence magazen yon sekans ti jan chèk asire rekonesans nan mesaj la entegre. Metòd estatik getEncryptingFileParameters retounen paramèt yo nan dosye a espesifye ak karakteristik yo nan mesaj potansyèl la.

Metòd algorithm encrypt klas GIFEncryptorByLSBMethod:

Esteganografi nan GIF

Ak kòd li:

@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 ak kòd sous metòd la decrypt klas GIFEncryptorByLSBMethod:

Esteganografi nan 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);
}

Aplikasyon klas la GIFEncryptorByPaletteExtensionMethod pral menm jan an, se sèlman metòd ekonomize/lekti enfòmasyon ki diferan.

Nan klas la MainFrame metòd wrap yo dekri: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), trete rezilta yo nan metòd koòdone Encryptor ak kominike avèk itilizatè a, sa vle di louvri yon dyalòg seleksyon fichye, montre mesaj erè, elatriye; osi byen ke lòt metòd: openImage(), ki pèmèt itilizatè a chwazi yon imaj, exit(), ki soti aplikasyon an. Metòd sa yo rele soti nan Actionatik meni korespondan yo. Anplis de sa, klas sa a aplike metòd oksilyè: createComponents() - kreyasyon eleman fòm, loadImageFile(File f) — chaje yon imaj nan yon eleman espesyal nan yon dosye. Aplikasyon klas la GIFEncryptorByPaletteExtensionMethod menm jan ak aplikasyon klas la GIFEncryptorByLSBMethod, diferans prensipal la se nan fason bytes mesaj yo ekri ak li nan palèt la.

Operasyon pwogram lan

Metòd LBS

Ann di gen yon imaj tankou sa a:

Esteganografi nan GIF

Nan imaj sa a, palèt la konsiste de 256 koulè (tankou Paint sove). Premye kat koulè yo se: blan, nwa, wouj, vèt. Lòt koulè yo nwa. Sekans bit palèt mondyal la pral jan sa a:

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

Esteganografi nan GIF

Yon fwa ke mesaj la entegre, moso souliye yo pral ranplase ak ti moso ki soti nan mesaj la. Imaj la ki kapab lakòz prèske pa diferan de orijinal la.

Original
Imaj ak mesaj entegre

Esteganografi nan GIF
Esteganografi nan GIF

Metòd ekspansyon palèt

Lè ou ouvri yon imaj ki gen yon mesaj lè l sèvi avèk metòd sa a, ou pral wè foto sa a:

Esteganografi nan GIF

Li klè ke metòd sa a pa pral travay pou aktivite espyonaj plen véritable, epi li ka mande pou plis chifreman nan mesaj la.

Chidere / dechifre nan imaj anime travay menm jan ak imaj estatik regilye, men animasyon an pa kase.

Sous yo itilize:

Download:

Sous: www.habr.com

Add nouvo kòmantè