Steganography amin'ny GIF

fampidirana

Fiarahabana.
Vao tsy ela akory izay, fony aho nianatra tany amin'ny oniversite, dia nisy fampianarana momba ny fitsipi-pifehezana "Software amin'ny fiarovana ny fampahalalana." Ny andraikitra dia nitaky anay hamorona programa izay mampiditra hafatra ao anaty rakitra GIF. Nanapa-kevitra ny hanao izany amin'ny Java aho.

Ato amin'ity lahatsoratra ity dia mamaritra ny hevitra teorika sasany, ary koa ny fomba namoronana ity programa kely ity.

Ampahany teΓ΄ria

endrika GIF

GIF (Graphics Interchange Format - lamina mifanakalo sary) dia endrika mitahiry sary an-tsary, afaka mitahiry angona voatsindry tsy misy fahaverezan'ny kalitao amin'ny endrika hatramin'ny 256 loko. Ity endrika ity dia novolavolain'ny CompuServe tamin'ny 1987 (GIF87a) mba handefasana sary raster amin'ny tambajotra. Tamin'ny 1989, novana ny endrika (GIF89a), nampiana ny fanohanana ny mangarahara sy ny animation.

Ny rakitra GIF dia manana rafitra sakana. Ireo sakana ireo dia manana halavana raikitra foana (na miankina amin'ny sainam-pirenena sasany), noho izany dia saika tsy azo atao ny manao fahadisoana momba ny toerana misy ny sakana tsirairay. Ny firafitry ny sary GIF tsy mihetsika tsotra indrindra amin'ny endrika GIF89a:

Steganography amin'ny GIF

Amin'ireo sakana rehetra amin'ny rafitra, amin'ity tranga ity dia ho liana amin'ny bloc palette manerantany sy ny masontsivana tompon'andraikitra amin'ny palette isika:

  • CT - fisian'ny palette manerantany. Raha apetraka io saina io dia tsy maintsy manomboka avy hatrany aorian'ny fikandrana efijery lojika ny palette manerantany.
  • Size - ny haben'ny palette sy ny isan'ny loko eo amin'ny sary. Sanda ho an'ity parameter ity:

Size
Isan'ny loko
Haben'ny 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

Fomba fanafenana

Ireto fomba manaraka ireto dia hampiasaina hanafenana hafatra amin'ny rakitra sary:

  • LSB (Least Significant Bit) fomba
  • Fomba fanampiny palette

LSB fomba - fomba mahazatra amin'ny steganography. Anisan'izany ny fanoloana ireo bitika manan-danja farany ao amin'ny kaontenera (amin'ny tranga misy antsika, ny palette eran-tany) miaraka amin'ny bitika amin'ny hafatra miafina.

Ny programa dia hampiasa ny bitika roa farany amin'ny palette manerantany ho ampahany amin'ity fomba ity. Midika izany fa ho an'ny sary 24-bit, izay ny palette loko dia telo bytes ho an'ny mena, manga, ary maitso, aorian'ny fampidirana hafatra ao anatiny, ny singa loko tsirairay dia hiova amin'ny gradations 3/255 ambony indrindra. Ny fiovana toy izany, voalohany, dia tsy ho hita maso na sarotra ho tsikaritra amin'ny mason'ny olombelona, ​​​​ary faharoa, tsy ho hita amin'ny fitaovana famoahana fampahalalana ambany kalitao.

Ny habetsaky ny fampahalalana dia hiankina mivantana amin'ny haben'ny palette sary. Koa satria 256 loko ny haben'ny palette ambony indrindra, ary raha soratana amin'ny ampahany amin'ny loko tsirairay ny bitika hafatra roa, dia 192 bytes ny halavan'ny hafatra (miaraka amin'ny palette ambony indrindra amin'ny sary). Raha vao tafiditra ao amin'ny sary ny hafatra dia tsy miova ny haben'ny rakitra.

Fomba fanitarana palette, izay miasa ho an'ny rafitra GIF ihany. Hahomby indrindra amin'ny sary misy palette kely. Ny maha-zava-dehibe azy dia ny mampitombo ny haben'ny palette, ka manome toerana fanampiny hanoratana ireo bytes ilaina ho solon'ny bytes loko. Raha heverintsika fa loko 2 (6 bita) ny haben'ny palette kely indrindra, dia mety ho 256 Γ— 3–6 = 762 octet ny haben'ny hafatra tafiditra indrindra. Ny fatiantoka dia ny fiarovana kriptografika ambany; ny hafatra napetraka dia azo vakiana amin'ny alΓ lan'ny tonian-dahatsoratra rehetra raha toa ka tsy niharan'ny fanafenana fanampiny ilay hafatra.

Ampahany amin'ny fampiharana

Famolavolana fandaharana

Ny fitaovana ilaina rehetra amin'ny fampiharana ny algorithm encryption sy decryption dia ho tafiditra ao anatin'ilay fonosana com.tsarik.steganography. Ity fonosana ity dia misy ny interface Encryptor miaraka amin'ny fomba encrypt ΠΈ decrypt, Kilasy Binary, izay manome fahafahana miasa miaraka amin'ny arrays bit, ary koa kilasy miavaka UnableToEncryptException ΠΈ UnableToDecryptException, izay tokony ampiasaina amin'ny fomba interface tsara Encryptor raha misy lesoka amin'ny encoding sy decoding tsirairay avy.

Fonosana fandaharana lehibe com.tsarik.programs.gifed dia hampiditra kilasy programa runnable miaraka amin'ny fomba static main, mamela anao hampandeha ny programa; kilasy izay mitahiry ny masontsivana fandaharana; ary fonosana miaraka amin'ny kilasy hafa.

Ny fampiharana ny algorithm dia haseho ao anaty fonosana com.tsarik.programs.gifed.gif fianarana GIFEncryptorByLSBMethod ΠΈ GIFEncryptorByPaletteExtensionMethod. Ireo kilasy roa ireo dia hampihatra ny interface Encryptor.

Miorina amin'ny firafitry ny endrika GIF, azonao atao ny mamorona algorithm amin'ny fampidirana hafatra ao amin'ny palette sary:

Steganography amin'ny GIF

Mba hamaritana ny fisian'ny hafatra ao amin'ny sary iray, dia ilaina ny manampy ny filaharan'ny bits amin'ny fiandohan'ny hafatra, izay ny decoder mamaky voalohany sy manamarina ny marina. Raha tsy mifanaraka dia heverina fa tsy misy hafatra miafina ao amin'ny sary. Avy eo dia mila mamaritra ny halavan'ny hafatra ianao. Avy eo ny lahatsoratry ny hafatra mihitsy.

Diagram sarin'ny fampiharana manontolo:

Steganography amin'ny GIF

Fampiharana ny programa

Ny fampiharana ny programa manontolo dia azo zaraina ho singa roa: ny fampiharana ny encryption interface tsara sy ny fomba decryption Encryptor, any am-pianarana GIFEncryptorByLSBMethod ΠΈ GIFEncryptorByPaletteExtensionMethod, ary ny fampiharana ny mpampiasa interface tsara.

Diniho ny kilasy GIFEncryptorByLSBMethod.

Steganography amin'ny GIF

Fields firstLSBit ΠΈ secondLSBit mirakitra ny isan'ny bitika isaky ny byte amin'ny sary tokony hidirana ny hafatra sy avy amin'ny toerana tokony hamakiana ilay hafatra. SaHa checkSequence mitahiry filaharana bitika fanamarinana mba hahazoana antoka ny fanekena ny hafatra tafiditra. Fomba static getEncryptingFileParameters mamerina ny mason'ny rakitra voatondro sy ny toetran'ny hafatra mety.

Algorithm fomba encrypt kilasy GIFEncryptorByLSBMethod:

Steganography amin'ny GIF

Ary ny 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 sy loharano loharanon'ny fomba decrypt kilasy GIFEncryptorByLSBMethod:

Steganography amin'ny 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);
}

Fampiharana ny kilasy GIFEncryptorByPaletteExtensionMethod hitovy ihany, ny fomba fitahirizana/famakiana vaovao ihany no hafa.

Ao am-pianarana MainFrame Ny fomba fiasa wrapper dia nofaritana: encryptImage(Encryptor encryptor) ΠΈ decryptImage(Encryptor encryptor), fanodinana ny vokatry ny fomba interface tsara Encryptor ary mifandray amin'ny mpampiasa, izany hoe ny fanokafana fifanakalozan-dresaka momba ny fisafidianana ny rakitra, ny fanehoana hafatra diso, sns.; ary koa ny fomba hafa: openImage(), mamela ny mpampiasa hisafidy sary iray, exit(), izay mivoaka ny fampiharana. Ireo fomba ireo dia antsoina avy amin'ny Actionireo singa sakafo mifandraika amin'izany. Ity kilasy ity koa dia mampihatra fomba fanampiny: createComponents() - famoronana singa endrika, loadImageFile(File f) - fampidirana sary ho singa manokana avy amin'ny rakitra. Fampiharana ny kilasy GIFEncryptorByPaletteExtensionMethod mitovy amin'ny fampiharana kilasy GIFEncryptorByLSBMethod, ny fahasamihafana lehibe dia eo amin'ny fomba fanoratana sy famakiana hafatra avy amin'ny palette.

Fampandehanana fandaharana

LBS fomba

Andeha atao hoe misy sary toy izao:

Steganography amin'ny GIF

Amin'ity sary ity, ny palette dia misy loko 256 (raha mitahiry ny Paint). Ny loko efatra voalohany dia: fotsy, mainty, mena, maitso. Ny loko hafa dia mainty. Ny filaharana bitika palette manerantany dia ho toy izao manaraka izao:

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

Steganography amin'ny GIF

Raha vao tafapetraka ny hafatra dia hosoloina ireo bits avy amin'ny hafatra ireo bits voatsindry. Ny sary vokarina dia saika tsy misy hafa amin'ny tany am-boalohany.

tany am-boalohany
Sary misy hafatra mipetaka

Steganography amin'ny GIF
Steganography amin'ny GIF

Fomba fanitarana palette

Rehefa manokatra sary misy hafatra mampiasa ity fomba ity ianao dia ho hitanao ity sary manaraka ity:

Steganography amin'ny GIF

Mazava fa ity fomba ity dia tsy mety amin'ny hetsika fitsikilovana feno, ary mety mitaky fanafenana fanampiny amin'ny hafatra.

Ny encryption/decryption amin'ny sary mihetsika dia miasa toy ny amin'ny sary static mahazatra, saingy tsy tapaka ny animation.

Loharano ampiasaina:

misintona:

Source: www.habr.com

Add a comment