Steganographie am GIF

Aféierung

Gréiss.
Net esou laang virun, wéi ech op der Uni studéiert hunn, gouf et Coursen an der Disziplin "Software Methoden vun Informatiounssécherheet." D'Aufgab huet eis erfuerdert e Programm ze kreéieren deen e Message a GIF-Dateien integréiert. Ech hu beschloss et am Java ze maachen.

An dësem Artikel wäert ech e puer theoretesch Punkten beschreiwen, wéi och wéi dëse klenge Programm erstallt gouf.

Theoreteschen Deel

GIF Format

GIF (Graphics Interchange Format - e Format fir Bildaustausch) ass e Format fir Grafikbilder ze späicheren, fäeg kompriméiert Daten ouni Qualitéitsverloscht an engem Format vu bis zu 256 Faarwen ze späicheren. Dëst Format gouf 1987 (GIF87a) vum CompuServe entwéckelt fir Rasterbilder iwwer Netzwierker ze vermëttelen. 1989 gouf d'Format geännert (GIF89a), Ënnerstëtzung fir Transparenz an Animatioun gouf bäigefüügt.

GIF Dateien hunn eng Blockstruktur. Dës Blocken hunn ëmmer eng fix Längt (oder et hänkt vun e puer Fändelen of), also ass et bal onméiglech fir e Feeler ze maachen iwwer wou all Block läit. D'Struktur vum einfachsten net-animéierten GIF Bild am GIF89a Format:

Steganographie am GIF

Vun all de Blocke vun der Struktur, an dësem Fall wäerte mir de globale Paletteblock an d'Parameteren verantwortlech fir d'Palette interesséieren:

  • CT - Präsenz vun enger globaler Palette. Wann dëse Fändel gesat ass, muss d'global Palette direkt nom logesche Bildschirmhandtak ufänken.
  • Size - Palette Gréisst an Zuel vu Faarwen am Bild. Wäerter fir dëse Parameter:

Gréisst
Zuel vu Faarwen
Palette Gréisst, 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

Verschlësselungsmethoden

Déi folgend Methode gi benotzt fir Messagen a Bilddateien ze verschlësselen:

  • LSB (Least Significant Bit) Method
  • Palette Additioun Method

LSB Method - eng gemeinsam Method vun steganography. Et besteet aus der Ersatz vun de leschte bedeitende Bits am Container (an eisem Fall, déi global Palette Bytes) mat de Bits vum verstoppte Message.

De Programm wäert déi lescht zwee Bits an de globale Palette Bytes als Deel vun dëser Method benotzen. Dëst bedeit datt fir e 24-Bit Bild, wou d'Faarfpalette dräi Bytes fir rout, blo a gréng ass, nodeems Dir e Message dran agebonnen hutt, all Faarfkomponent ëm maximal 3/255 Gradatiounen ännert. Esou eng Ännerung, éischtens, wäert onsichtbar oder schwéier fir de mënschlechen Aen ze bemierken, an zweetens, ass et net siichtbar op niddereg-Qualitéit Informatiounen Output Apparater.

D'Quantitéit un Informatioun hänkt direkt vun der Gréisst vun der Bildpalette of. Well déi maximal Gréisst vun der Palette 256 Faarwen ass, a wann zwee Message Bits an de Komponent vun all Faarf geschriwwe ginn, dann ass déi maximal Messagelängt (mat der maximaler Palette am Bild) 192 Bytes. Wann de Message am Bild agebonnen ass, ännert d'Dateigréisst net.

Palette Erweiderung Method, déi nëmme fir d'GIF Struktur funktionnéiert. Et wäert am effektivsten sinn op Biller mat enger klenger Palette. Seng Essenz ass datt et d'Gréisst vun der Palette vergréissert, doduerch zousätzlech Plaz ubitt fir déi néideg Bytes amplaz vun de Faarfbytes ze schreiwen. Wa mir berücksichtegen datt d'Mindestgréisst vun der Palette 2 Faarwen (6 Bytes) ass, da kann d'maximal Gréisst vun der embedded Message 256 × 3-6 = 762 Bytes sinn. Den Nodeel ass eng geréng kryptographesch Sécherheet; den Embedded Message kann mat all Texteditor gelies ginn wann de Message net un zousätzlech Verschlësselung ënnerworf gouf.

Praktesch Deel

Programm Design

All néideg Tools fir d'Verschlësselung an d'Entschlësselungsalgorithmen ëmzesetzen ginn am Package abegraff com.tsarik.steganography. Dëse Package enthält den Interface Encryptor mat Methoden encrypt и decrypt, Klass Binary, déi d'Fähigkeit ubitt fir mat Bit-Arrays ze schaffen, souwéi Ausnahmsklassen UnableToEncryptException и UnableToDecryptException, déi soll an Interface Methoden benotzt ginn Encryptor am Fall vu Kodéierungs- an Dekodéierungsfehler respektiv.

Haaptprogramm Package com.tsarik.programs.gifed wäert eng lafend Programm Klass mat enger statesch Method enthalen main, erlaabt Iech de Programm ze lafen; eng Klass déi Programmparameter späichert; a Packagen mat anere Klassen.

D'Ëmsetzung vun den Algorithmen selwer gëtt am Package presentéiert com.tsarik.programs.gifed.gif Klassen GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Béid vun dëse Klassen wäerten d'Interface implementéieren Encryptor.

Baséierend op der Struktur vum GIF-Format kënnt Dir en allgemenge Algorithmus erstellen fir e Message an d'Bildpalette aféieren:

Steganographie am GIF

Fir d'Präsenz vun engem Message an engem Bild ze bestëmmen, ass et néideg eng gewësse Sequenz vu Bits un den Ufank vun der Noriicht ze addéieren, déi den Decoder als éischt liest a kontrolléiert d'Korrektheet. Wann et net passt, da gëtt et ugesinn datt et kee verstoppte Message am Bild ass. Als nächst musst Dir d'Längt vum Message uginn. Dann den Text vum Message selwer.

Klassendiagramm vun der ganzer Applikatioun:

Steganographie am GIF

Ëmsetzung vum Programm

D'Ëmsetzung vum ganze Programm kann an zwee Komponenten opgedeelt ginn: Ëmsetzung vun der Interface Verschlësselung an Entschlësselungsmethoden Encryptor, an de Klassen GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, an d'Ëmsetzung vun der User-Interface.

Betruecht der Klass GIFEncryptorByLSBMethod.

Steganographie am GIF

Felder firstLSBit и secondLSBit enthalen d'Zuel vu Bits vun all Byte vum Bild an deem de Message sollt aginn a vu wou de Message gelies soll ginn. Feld checkSequence späichert eng Scheckbitsequenz fir d'Unerkennung vum Embedded Message ze garantéieren. Statesch Method getEncryptingFileParameters gëtt d'Parameter vun der spezifizéierter Datei an d'Charakteristiken vum potenziellen Message zréck.

Method Algorithmus encrypt Grad GIFEncryptorByLSBMethod:

Steganographie am GIF

A säi 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();
}

Algorithmus a Quellcode vun der Method decrypt Grad GIFEncryptorByLSBMethod:

Steganographie am 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);
}

Ëmsetzung vun der Klass GIFEncryptorByPaletteExtensionMethod wäert ähnlech sinn, nëmmen d'Method fir Informatioun ze späicheren / liesen ass anescht.

An der Klass MainFrame Wrapper Methoden ginn beschriwwen: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), Veraarbechtung vun de Resultater vun Interface Methoden Encryptor an Interaktioun mam Benotzer, dh e Fichier Auswiel Dialog opzemaachen, Feeler Messagen ze weisen, etc .; wéi och aner Methoden: openImage(), erlaabt de Benotzer e Bild ze wielen, exit(), déi d'Applikatioun ausléisst. Dës Methoden sinn genannt aus Actionentspriechend Menüartikelen. Dës Klass implementéiert zousätzlech Hëllefsmethoden: createComponents() - Schafung vu Formkomponenten, loadImageFile(File f) - Luede e Bild an e spezielle Komponent aus enger Datei. Ëmsetzung vun der Klass GIFEncryptorByPaletteExtensionMethod ähnlech zu der Klass Ëmsetzung GIFEncryptorByLSBMethod, den Haaptunterschied ass an der Aart a Weis wéi Message Bytes geschriwwe ginn an aus der Palette gelies ginn.

Programm Operatioun

LBS Method

Loosst eis soen datt et e Bild ass wéi dëst:

Steganographie am GIF

An dësem Bild besteet d'Palette aus 256 Faarwen (wéi Paint späichert). Déi éischt véier Faarwen sinn: wäiss, schwaarz, rout, gréng. Aner Faarwen si schwaarz. Déi global Palette Bit Sequenz wäert wéi follegt sinn:

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

Steganographie am GIF

Wann de Message agebonnen ass, ginn déi ënnersträicht Bits mat de Bits aus der Noriicht ersat. Dat resultéierend Bild ass bal net anescht wéi d'Original.

Original
Bild mat embedded Message

Steganographie am GIF
Steganographie am GIF

Palette Erweiderung Method

Wann Dir e Bild opmaacht mat engem Message mat dëser Methode, gesitt Dir déi folgend Bild:

Steganographie am GIF

Et ass kloer datt dës Method net fir vollwäerteg Spionageaktivitéite funktionnéiert, a kann zousätzlech Verschlësselung vum Message erfuerderen.

Verschlësselung / Entschlësselung an animéierten Biller funktionnéiert grad wéi a reguläre statesche Biller, awer d'Animatioun ass net gebrach.

Benotzt Quellen:

Download:

Source: will.com

Setzt e Commentaire