Steganography i GIF

Réamhrá

Beannachtaí.
Ní fada ó shin, agus mé ag staidéar san ollscoil, bhí obair chúrsa sa disciplín “Software methods of information security”. D'éiligh an tasc orainn clár a chruthú a neadódh teachtaireacht i gcomhaid GIF. Chinn mé é a dhéanamh i Java.

San Airteagal seo déanfaidh mé cur síos ar roinnt pointí teoiriciúla, chomh maith le conas a cruthaíodh an clár beag seo.

Cuid theoiriciúil

Formáid GIF

Is formáid é GIF (Formáid Idirmhalartaithe Grafaic - formáid chun íomhánna a mhalartú) chun íomhánna grafacha a stóráil, atá in ann sonraí comhbhrúite a stóráil gan aon chaillteanas cáilíochta i bhformáid suas le 256 dathanna. D'fhorbair CompuServe an fhormáid seo i 1987 (GIF87a) chun íomhánna raster a tharchur thar líonraí. In 1989, athraíodh an fhormáid (GIF89a), cuireadh tacaíocht le haghaidh trédhearcachta agus beochana leis.

Tá struchtúr bloc ag comhaid GIF. Bíonn fad seasta ag na bloic seo i gcónaí (nó braitheann sé ar roinnt bratacha), agus mar sin tá sé beagnach dodhéanta botún a dhéanamh faoin áit a bhfuil gach bloc suite. Struchtúr na híomhá GIF neamhbheoite is simplí i bhformáid GIF89a:

Steganography i GIF

As na bloic go léir den struchtúr, sa chás seo beidh suim againn sa bhloc pailéad domhanda agus na paraiméadair atá freagrach as an pailéad:

  • CT — pailéad domhanda a bheith ann. Má tá an bhratach seo socraithe, caithfidh an pailéad domhanda tosú díreach tar éis láimhseáil an scáileáin loighciúil.
  • Size — méid pailéad agus líon na dathanna sa phictiúr. Luachanna don pharaiméadar seo:

méid
Líon na dathanna
Méid pailéad, bearta

7
256
768

6
128
384

5
64
192

4
32
96

3
16
48

2
8
24

1
4
12

0
2
6

Modhanna criptithe

Bainfear úsáid as na modhanna seo a leanas chun teachtaireachtaí a chriptiú i gcomhaid íomhá:

  • Modh LSB (Giotán Ar A laghad Suntasach).
  • Modh breise pailéad

Modh LSB - modh coitianta steganography. Is éard atá ann ná na giotán suntasacha deiridh sa choimeádán (inár gcás, na bearta pailéad domhanda) a athsholáthar le giotán na teachtaireachta i bhfolach.

Úsáidfidh an clár an dá ghiotán deiridh sna bearta pailéad domhanda mar chuid den mhodh seo. Ciallaíonn sé seo gur le haghaidh íomhá 24-giotán, áit a bhfuil an pailéad dathanna trí beart le haghaidh dearg, gorm, agus glas, tar éis leabú teachtaireacht isteach é, beidh gach comhpháirt dath a athrú faoi uasmhéid de 3/255 gráduithe. Beidh athrú den sórt sin, ar an gcéad dul síos, dofheicthe nó deacair a thabhairt faoi deara don tsúil dhaonna, agus ar an dara dul síos, ní bheidh sé le feiceáil ar fheistí aschuir faisnéise ar chaighdeán íseal.

Beidh méid na faisnéise ag brath go díreach ar mhéid an pailéad íomhá. Ós rud é gurb é 256 dathanna uasmhéid an phailéad, agus má scríobhtar dhá ghiotán teachtaireachta isteach sa chomhpháirt de gach dath, ansin is é 192 beart an t-uasfhad teachtaireachta (leis an pailéad uasta san íomhá). Nuair a bheidh an teachtaireacht leabaithe san íomhá, ní athraíonn méid an chomhaid.

Modh leathnú pailéad, a oibríonn ach amháin le haghaidh struchtúr GIF. Beidh sé is éifeachtaí ar íomhánna le pailéad beag. Is é a bunúsach ná go méadaíonn sé méid an pailéad, rud a chuireann spás breise ar fáil chun na bearta riachtanacha a scríobh in ionad na mbeart dath. Má mheasann muid gurb é 2 dhath (6 bytes) íosmhéid an phailéad, ansin is féidir uasmhéid na teachtaireachta leabaithe a bheith 256 × 3-6 = 762 bytes. Is é an míbhuntáiste ná slándáil chripteagrafach íseal; is féidir an teachtaireacht leabaithe a léamh le haon eagarthóir téacs mura bhfuil an teachtaireacht faoi réir criptithe breise.

Cuid phraiticiúil

Dearadh clár

Áireofar sa phacáiste gach uirlis riachtanach chun halgartaim criptithe agus díchriptithe a chur chun feidhme com.tsarik.steganography. Áiríonn an pacáiste seo an comhéadan Encryptor le modhanna encrypt и decrypt, Aicme Binary, a sholáthraíonn an cumas oibriú le eagair ghiotán, chomh maith le ranganna eisceachta UnableToEncryptException и UnableToDecryptException, ba cheart a úsáid i modhanna comhéadan Encryptor i gcás earráidí ionchódaithe agus díchódaithe faoi seach.

Pacáiste príomhchláir com.tsarik.programs.gifed áireofar leis rang cláir inrite le modh statach main, rud a ligeann duit an clár a rith; aicme a stórálann paraiméadair clár; agus pacáistí le ranganna eile.

Cuirfear cur i bhfeidhm na n-halgartaim féin i láthair sa phacáiste com.tsarik.programs.gifed.gif ranganna GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Cuirfidh an dá rang seo an comhéadan i bhfeidhm Encryptor.

Bunaithe ar struchtúr an fhormáid GIF, is féidir leat algartam ginearálta a chruthú chun teachtaireacht a thabhairt isteach sa pailéad íomhánna:

Steganography i GIF

Chun láithreacht teachtaireachta in íomhá a chinneadh, is gá seicheamh áirithe giotán a chur le tús na teachtaireachta, a léann an díchódóir ar dtús agus seiceálann sé le cruinneas. Mura n-oireann sé, ansin meastar nach bhfuil aon teachtaireacht i bhfolach san íomhá. Ansin ní mór duit fad na teachtaireachta a shonrú. Ansin téacs na teachtaireachta féin.

Léaráid ranga den fheidhmchlár iomlán:

Steganography i GIF

Cur i bhfeidhm an chláir

Is féidir cur i bhfeidhm an chláir ar fad a roinnt ina dhá chomhpháirt: cur i bhfeidhm modhanna criptithe agus díchriptithe comhéadan Encryptor, sna ranganna GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, agus an comhéadan úsáideora a chur i bhfeidhm.

Smaoinigh ar an rang GIFEncryptorByLSBMethod.

Steganography i GIF

Réimse firstLSBit и secondLSBit go mbeidh líon na ngiotán de gach beart den íomhá inar cheart an teachtaireacht a chur isteach agus ón áit ar cheart an teachtaireacht a léamh. Gort checkSequence stóráiltear seicheamh giotán seiceála chun aitheantas na teachtaireachta leabaithe a chinntiú. Modh statach getEncryptingFileParameters tuairisceáin paraiméadair an chomhaid shonraithe agus tréithe na teachtaireachta féideartha.

Modh algartam encrypt rang GIFEncryptorByLSBMethod:

Steganography i GIF

Agus a chód:

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

Algartam agus cód foinse an mhodha decrypt rang GIFEncryptorByLSBMethod:

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

Cur i bhfeidhm an ranga GIFEncryptorByPaletteExtensionMethod mar a chéile, níl ach an modh chun faisnéis a shábháil/léamh difriúil.

Sa rang MainFrame Déantar cur síos ar mhodhanna fillte: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), torthaí modhanna comhéadan a phróiseáil Encryptor agus idirghníomhú leis an úsáideoir, i.e. dialóg roghnúcháin comhad a oscailt, teachtaireachtaí earráide a thaispeáint, etc.; chomh maith le modhanna eile: openImage(), ag ligean don úsáideoir íomhá a roghnú, exit(), a fhágann an feidhmchlár. Tugtar ó na modhanna seo Action'na míreanna roghchláir comhfhreagracha. Cuireann an rang seo modhanna cúnta i bhfeidhm freisin: createComponents() - cruthú comhpháirteanna foirme, loadImageFile(File f) — íomhá a luchtú isteach i gcomhpháirt speisialta as comhad. Cur i bhfeidhm an ranga GIFEncryptorByPaletteExtensionMethod cosúil le cur i bhfeidhm an ranga GIFEncryptorByLSBMethod, is é an príomhdhifríocht ná an bealach a scríobhtar agus a léitear bearta teachtaireachta ón bpailéad.

Oibriú cláir

Modh LBS

Ligean le rá go bhfuil íomhá mar seo:

Steganography i GIF

San íomhá seo, tá an pailéad comhdhéanta de 256 dathanna (mar a shábhálann Paint). Is iad na chéad cheithre dathanna: bán, dubh, dearg, glas. Tá dathanna eile dubh. Beidh an seicheamh giotán pailéad domhanda mar seo a leanas:

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

Steganography i GIF

Nuair a bheidh an teachtaireacht leabaithe, cuirfear na giotáin ón teachtaireacht in ionad na ngiotán a bhfuil líne fúthu. Tá an íomhá mar thoradh air beagnach aon difriúil ón íomhá bunaidh.

Bunaidh
Íomhá le teachtaireacht leabaithe

Steganography i GIF
Steganography i GIF

Modh leathnú pailéad

Nuair a osclaíonn tú íomhá ina bhfuil teachtaireacht ag baint úsáide as an modh seo, feicfidh tú an pictiúr seo a leanas:

Steganography i GIF

Tá sé soiléir nach n-oibreoidh an modh seo le haghaidh gníomhaíochtaí spiaireachta lán-chuimsitheach, agus d'fhéadfadh go mbeadh gá le criptiú breise ar an teachtaireacht.

Oibríonn criptiú/díchriptiú in íomhánna beoite díreach mar a dhéantar in íomhánna statacha rialta, ach níl an beochan briste.

Foinsí a úsáideadh:

Íoslódáil:

Foinse: will.com

Add a comment