Steganography ma GIF

Hōʻike

Aloha ʻoe.
ʻAʻole i lōʻihi ma mua, i koʻu aʻo ʻana ma ke kulanui, aia kahi haʻawina ma ke aʻo ʻana "Software method of information security." Pono mākou e hana i kahi papahana e hoʻokomo i kahi leka ma nā faila GIF. Ua hoʻoholo wau e hana ma Java.

Ma kēia ʻatikala e wehewehe wau i kekahi mau manaʻo kumu, a me ke ʻano o ka hana ʻana o kēia polokalamu liʻiliʻi.

ʻO keʻano heʻe

ʻano GIF

ʻO GIF (Graphics Interchange Format - he ʻano no ka hoʻololi ʻana i nā kiʻi) he ʻano no ka mālama ʻana i nā kiʻi kiʻi, hiki ke mālama i ka ʻikepili i hoʻopaʻa ʻia me ka nalowale ʻole o ka maikaʻi ma ke ʻano a hiki i 256 kala. Ua kūkulu ʻia kēia ʻano i ka makahiki 1987 (GIF87a) e CompuServe no ka hoʻouna ʻana i nā kiʻi raster ma luna o nā pūnaewele. I ka makahiki 1989, ua hoʻololi ʻia ke ʻano (GIF89a), ua hoʻohui ʻia ke kākoʻo no ka ʻike a me ka animation.

Loaʻa i nā faila GIF kahi ʻano poloka. Loaʻa mau ka lōʻihi o kēia mau poloka (a i ʻole ma muli o kekahi mau hae), no laila ʻaneʻane hiki ʻole ke kuhi hewa i kahi o kēlā me kēia poloka. ʻO ke ʻano o ke kiʻi GIF non-animated maʻalahi ma GIF89a format:

Steganography ma GIF

ʻO nā poloka āpau o ka hale, i kēia hihia e makemake mākou i ka poloka palette honua a me nā ʻāpana kuleana no ka palette:

  • CT - ke alo o kahi palette honua. Inā hoʻonoho ʻia kēia hae, pono e hoʻomaka koke ka palette honua ma hope o ka paʻa ʻana o ka pale pono.
  • Size - ka nui o ka palette a me ka helu o nā kala i ke kiʻi. Nā waiwai no kēia ʻāpana:

Size
Ka helu o nā kala
Ka nui o ka palette, 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

Nā ʻano hoʻopunipuni

E hoʻohana ʻia nā ʻano hana e hoʻopili ai i nā memo ma nā faila kiʻi:

  • LSB (Least Significant Bit).
  • ʻano hoʻohui palette

LSB ala - he ala maʻamau o steganography. ʻO ia ka hoʻololi ʻana i nā ʻāpana koʻikoʻi hope loa i loko o ka pahu (i kā mākou hihia, nā bytes palette honua) me nā ʻāpana o ka memo huna.

E hoʻohana ka polokalamu i nā ʻāpana hope ʻelua i nā bytes palette honua ma ke ʻano o kēia ʻano. ʻO ia hoʻi, no ke kiʻi 24-bit, kahi o ka papa kala he ʻekolu paita no ka ʻulaʻula, ka uliuli, a me ka ʻōmaʻomaʻo, ma hope o ka hoʻokomo ʻana i kahi leka i loko, e hoʻololi ʻia kēlā me kēia ʻāpana waihoʻoluʻu e ka nui o 3/255 gradations. ʻO ia hoʻololi, ʻo ka mea mua, ʻaʻole ʻike ʻia a paʻakikī paha ke ʻike ʻia e ka maka o ke kanaka, a ʻo ka lua, ʻaʻole ia e ʻike ʻia ma nā mea hoʻopuka ʻike haʻahaʻa haʻahaʻa.

ʻO ka nui o ka ʻike e pili pono i ka nui o ka palette kiʻi. No ka mea he 256 kala ka nui loa o ka palette, a inā i kākau ʻia ʻelua mau memo i loko o ka ʻāpana o kēlā me kēia kala, a laila ʻo ka lōʻihi o ka memo (me ka palette kiʻekiʻe o ke kiʻi) he 192 bytes. Ke hoʻokomo ʻia ka memo i ke kiʻi, ʻaʻole loli ka nui o ka faila.

ʻano hoʻonui palette, e hana wale ana no ka hana GIF. E ʻoi aku ka maikaʻi ma nā kiʻi me kahi palette liʻiliʻi. ʻO kona kumu, ʻo ia ka hoʻonui ʻana i ka nui o ka palette, a laila e hāʻawi i kahi wahi hou no ke kākau ʻana i nā bytes pono ma kahi o nā bytes kala. Inā mākou e noʻonoʻo ʻo ka liʻiliʻi liʻiliʻi o ka palette he 2 waihoʻoluʻu (6 bytes), a laila hiki ke kiʻekiʻe loa o ka memo i hoʻokomo ʻia he 256 × 3–6 = 762 bytes. ʻO ka hemahema ʻo ka palekana cryptographic haʻahaʻa; hiki ke heluhelu ʻia ka memo i hoʻopili ʻia me ka hoʻohana ʻana i kekahi mea hoʻoponopono kikokikona inā ʻaʻole i hoʻopili ʻia ka memo i kahi hoʻopuna hou.

ʻO kaʻaoʻao kūpono

Hoʻolālā papahana

E hoʻokomo ʻia nā mea pono āpau no ka hoʻokō ʻana i ka hoʻopili ʻana a me ka decryption algorithms i loko o ka pūʻolo com.tsarik.steganography. Aia kēia pūʻolo i ka interface Encryptor me nā ʻano hana encrypt и decrypt, Papa Binary, ka mea e hāʻawi i ka hiki ke hana me ka bit arrays, a me nā papa ʻokoʻa UnableToEncryptException и UnableToDecryptException, pono e hoʻohana ʻia i nā kaʻina hana Encryptor i ka hihia o ka hoʻopaʻa ʻana a me ka decoding hewa.

Pūʻolo papahana nui com.tsarik.programs.gifed e hoʻokomo i kahi papa papahana runnable me ke ʻano static main, hiki iā ʻoe ke holo i ka papahana; he papa e mālama ana i nā palena papahana; a me nā pūʻolo me nā papa ʻē aʻe.

E hōʻike ʻia ka hoʻokō ʻana o nā algorithm iā lākou iho i ka pā com.tsarik.programs.gifed.gif nā papa GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. E hoʻokō kēia mau papa ʻelua i ka interface Encryptor.

Ma muli o ke ʻano o ke ʻano GIF, hiki iā ʻoe ke hana i kahi algorithm maʻamau no ka hoʻokomo ʻana i kahi leka i loko o ka papa kiʻi:

Steganography ma GIF

No ka hoʻoholo ʻana i ka loaʻa ʻana o kahi memo ma kahi kiʻi, pono e hoʻohui i kahi kaʻina o nā bits i ka hoʻomaka ʻana o ka memo, kahi e heluhelu mua ai ka decoder a nānā i ka pololei. Inā ʻaʻole i kūlike, a laila manaʻo ʻia ʻaʻohe memo huna ma ke kiʻi. A laila pono ʻoe e kuhikuhi i ka lōʻihi o ka memo. A laila ka kikokikona o ka memo pono'ī.

Kiʻi papa o ka noi holoʻokoʻa:

Steganography ma GIF

Hoʻokō i ka papahana

Hiki ke hoʻokaʻawale ʻia ka hoʻokō ʻana o ka papahana holoʻokoʻa i ʻelua mau ʻāpana: hoʻokō i ka hoʻopili hoʻopili a me nā ʻano decryption Encryptor, ma na papa GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, a me ka hoʻokō ʻana i ka mea hoʻohana.

E noʻonoʻo i ka papa GIFEncryptorByLSBMethod.

Steganography ma GIF

nā māla firstLSBit и secondLSBit Loaʻa nā helu o nā bits o kēlā me kēia byte o ke kiʻi kahi e hoʻokomo ʻia ai ka memo a mai kahi e heluhelu ʻia ai ka memo. Kihapai checkSequence mālama i kahi kaʻina bit check e hōʻoia i ka ʻike ʻana i ka memo i hoʻokomo ʻia. ʻano ʻano paʻa getEncryptingFileParameters hoʻihoʻi i nā ʻāpana o ka faila i kuhikuhi ʻia a me nā ʻano o ka memo hiki.

Kaʻina algorithm encrypt keka GIFEncryptorByLSBMethod:

Steganography ma GIF

A me kāna code:

@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 a me ke code kumu o ke ala decrypt keka GIFEncryptorByLSBMethod:

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

Hoʻokō o ka papa GIFEncryptorByPaletteExtensionMethod e like, ʻokoʻa ke ʻano o ka mālama ʻana/heluhelu ʻana i ka ʻike.

I ka papa MainFrame Ua wehewehe ʻia ke ʻano o ka wrapper: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), ka hoʻoili ʻana i nā hopena o nā ʻano hana interface Encryptor a me ka launa pū ʻana me ka mea hoʻohana, ʻo ia hoʻi ka wehe ʻana i kahi kūkākūkā koho faila, e hōʻike ana i nā memo hewa, etc.; a me nā ʻano hana ʻē aʻe: openImage(), hiki i ka mea hoʻohana ke koho i kiʻi, exit(), ka mea i puka i ka palapala noi. Kāhea ʻia kēia mau ʻano mai Action's pili menu 'ikamu. Hoʻohana pū kēia papa i nā ʻano kōkua: createComponents() - ka hana ʻana i nā ʻāpana form, loadImageFile(File f) - ke hoʻouka ʻana i kahi kiʻi i loko o kahi ʻāpana kūikawā mai kahi faila. Hoʻokō o ka papa GIFEncryptorByPaletteExtensionMethod like me ka hoʻokō papa GIFEncryptorByLSBMethod, ʻo ka ʻokoʻa nui ma ke ʻano o ka kākau ʻana a me ka heluhelu ʻana i nā memo mai ka palette.

Hana papahana

LBS ala

E ʻōlelo kākou aia kekahi kiʻi e like me kēia:

Steganography ma GIF

Ma kēia kiʻi, he 256 mau kala (e like me ka mālama ʻana o ka pena). ʻO nā kala mua ʻehā: keʻokeʻo, ʻeleʻele, ʻulaʻula, ʻōmaʻomaʻo. ʻO nā kala ʻē aʻe he ʻeleʻele. Penei ke kaʻina bit palette honua:

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

Steganography ma GIF

Ke hoʻokomo ʻia ka memo, e hoʻololi ʻia nā ʻāpana i kaha ʻia me nā ʻāpana mai ka memo. ʻAʻole ʻokoʻa ke kiʻi i loaʻa mai ke kumu.

Nā kumu
Kiʻi me ka memo i hoʻokomo ʻia

Steganography ma GIF
Steganography ma GIF

ʻano hoʻonui palette

Ke wehe ʻoe i kahi kiʻi i loaʻa kahi memo me kēia ʻano hana, e ʻike ʻoe i kēia kiʻi:

Steganography ma GIF

Ua maopopo ʻaʻole e hana kēia ʻano hana no nā hana kiu piha piha, a makemake paha i kahi hoʻopili hou o ka memo.

Hana ʻia ka hoʻopunipuni/decryption i nā kiʻi animated e like me nā kiʻi static maʻamau, akā ʻaʻole i haki ka animation.

Nā kumu i hoʻohana ʻia:

Hoʻoili:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka