GIFలో స్టెగానోగ్రఫీ

పరిచయం

శుభాకాంక్షలు.
చాలా కాలం క్రితం, నేను విశ్వవిద్యాలయంలో చదువుతున్నప్పుడు, "సమాచార భద్రత యొక్క సాఫ్ట్‌వేర్ పద్ధతులు" అనే విభాగంలో ఒక కోర్స్‌వర్క్ ఉంది. GIF ఫైల్‌లలో సందేశాన్ని పొందుపరిచే ప్రోగ్రామ్‌ను సృష్టించడం అసైన్‌మెంట్ మాకు అవసరం. నేను జావాలో చేయాలని నిర్ణయించుకున్నాను.

ఈ వ్యాసంలో నేను కొన్ని సైద్ధాంతిక అంశాలను వివరిస్తాను, అలాగే ఈ చిన్న ప్రోగ్రామ్ ఎలా సృష్టించబడిందో వివరిస్తాను.

సైద్ధాంతిక భాగం

GIF ఫార్మాట్

GIF (గ్రాఫిక్స్ ఇంటర్‌చేంజ్ ఫార్మాట్ - చిత్రాలను మార్పిడి చేసుకునే ఫార్మాట్) అనేది గ్రాఫిక్ చిత్రాలను నిల్వ చేయడానికి ఒక ఫార్మాట్, ఇది 256 రంగుల ఫార్మాట్‌లో నాణ్యతను కోల్పోకుండా కంప్రెస్డ్ డేటాను నిల్వ చేయగలదు. నెట్‌వర్క్‌ల ద్వారా రాస్టర్ చిత్రాలను ప్రసారం చేయడానికి CompuServe ద్వారా 1987లో (GIF87a) ఈ ఫార్మాట్ అభివృద్ధి చేయబడింది. 1989లో, ఫార్మాట్ సవరించబడింది (GIF89a), పారదర్శకత మరియు యానిమేషన్‌కు మద్దతు జోడించబడింది.

GIF ఫైల్‌లు బ్లాక్ నిర్మాణాన్ని కలిగి ఉంటాయి. ఈ బ్లాక్‌లు ఎల్లప్పుడూ స్థిరమైన పొడవును కలిగి ఉంటాయి (లేదా ఇది కొన్ని ఫ్లాగ్‌లపై ఆధారపడి ఉంటుంది), కాబట్టి ప్రతి బ్లాక్ ఎక్కడ ఉందో తప్పు చేయడం దాదాపు అసాధ్యం. GIF89a ఆకృతిలో సరళమైన యానిమేటెడ్ కాని GIF చిత్రం యొక్క నిర్మాణం:

GIFలో స్టెగానోగ్రఫీ

నిర్మాణం యొక్క అన్ని బ్లాక్‌లలో, ఈ సందర్భంలో మేము గ్లోబల్ పాలెట్ బ్లాక్ మరియు పాలెట్‌కు బాధ్యత వహించే పారామితులపై ఆసక్తి కలిగి ఉంటాము:

  • CT - ప్రపంచ పాలెట్ ఉనికి. ఈ ఫ్లాగ్ సెట్ చేయబడితే, లాజికల్ స్క్రీన్ హ్యాండిల్ తర్వాత గ్లోబల్ పాలెట్ వెంటనే ప్రారంభం కావాలి.
  • Size - పాలెట్ పరిమాణం మరియు చిత్రంలో రంగుల సంఖ్య. ఈ పరామితి కోసం విలువలు:

పరిమాణం
రంగుల సంఖ్య
పాలెట్ పరిమాణం, బైట్లు

7
256
768

6
128
384

5
64
192

4
32
96

3
16
48

2
8
24

1
4
12

0
2
6

ఎన్క్రిప్షన్ పద్ధతులు

ఇమేజ్ ఫైల్‌లలో సందేశాలను గుప్తీకరించడానికి క్రింది పద్ధతులు ఉపయోగించబడతాయి:

  • LSB (తక్కువ ముఖ్యమైన బిట్) పద్ధతి
  • పాలెట్ జోడింపు పద్ధతి

LSB పద్ధతి - స్టెగానోగ్రఫీ యొక్క సాధారణ పద్ధతి. ఇది కంటైనర్‌లోని చివరి ముఖ్యమైన బిట్‌లను (మా విషయంలో, గ్లోబల్ పాలెట్ బైట్‌లు) దాచిన సందేశం యొక్క బిట్‌లతో భర్తీ చేస్తుంది.

ప్రోగ్రామ్ ఈ పద్ధతిలో భాగంగా గ్లోబల్ పాలెట్ బైట్‌లలో చివరి రెండు బిట్‌లను ఉపయోగిస్తుంది. దీనర్థం, 24-బిట్ ఇమేజ్ కోసం, ఎరుపు, నీలం మరియు ఆకుపచ్చ రంగుల కోసం ప్యాలెట్ రంగు మూడు బైట్‌లుగా ఉంటుంది, అందులో సందేశాన్ని పొందుపరిచిన తర్వాత, ప్రతి రంగు భాగం గరిష్టంగా 3/255 స్థాయిల వరకు మారుతుంది. అటువంటి మార్పు, మొదటిది, మానవ కంటికి కనిపించకుండా లేదా కష్టంగా ఉంటుంది మరియు రెండవది, ఇది తక్కువ-నాణ్యత గల సమాచార అవుట్‌పుట్ పరికరాలలో కనిపించదు.

సమాచారం మొత్తం నేరుగా చిత్ర పాలెట్ పరిమాణంపై ఆధారపడి ఉంటుంది. ప్యాలెట్ యొక్క గరిష్ట పరిమాణం 256 రంగులు మరియు ప్రతి రంగు యొక్క కాంపోనెంట్‌లో రెండు సందేశ బిట్‌లు వ్రాయబడితే, గరిష్ట సందేశ పొడవు (చిత్రంలో గరిష్ట పాలెట్‌తో) 192 బైట్లు. సందేశాన్ని చిత్రంలో పొందుపరిచిన తర్వాత, ఫైల్ పరిమాణం మారదు.

పాలెట్ విస్తరణ పద్ధతి, ఇది GIF నిర్మాణం కోసం మాత్రమే పని చేస్తుంది. ఇది చిన్న పాలెట్‌తో ఉన్న చిత్రాలపై అత్యంత ప్రభావవంతంగా ఉంటుంది. దీని సారాంశం ఏమిటంటే ఇది పాలెట్ యొక్క పరిమాణాన్ని పెంచుతుంది, తద్వారా రంగు బైట్‌ల స్థానంలో అవసరమైన బైట్‌లను వ్రాయడానికి అదనపు స్థలాన్ని అందిస్తుంది. మేము ప్యాలెట్ యొక్క కనిష్ట పరిమాణం 2 రంగులు (6 బైట్లు) అని భావిస్తే, అప్పుడు పొందుపరిచిన సందేశం యొక్క గరిష్ట పరిమాణం 256 × 3–6 = 762 బైట్లు కావచ్చు. ప్రతికూలత తక్కువ క్రిప్టోగ్రాఫిక్ భద్రత; సందేశం అదనపు ఎన్‌క్రిప్షన్‌కు లోబడి ఉండకపోతే పొందుపరిచిన సందేశాన్ని ఏదైనా టెక్స్ట్ ఎడిటర్ ఉపయోగించి చదవవచ్చు.

ప్రాక్టికల్ భాగం

ప్రోగ్రామ్ డిజైన్

ఎన్‌క్రిప్షన్ మరియు డిక్రిప్షన్ అల్గారిథమ్‌లను అమలు చేయడానికి అవసరమైన అన్ని సాధనాలు ప్యాకేజీలో చేర్చబడతాయి com.tsarik.steganography. ఈ ప్యాకేజీలో ఇంటర్‌ఫేస్ ఉంటుంది Encryptor పద్ధతులతో encrypt и decrypt, తరగతి Binary, ఇది బిట్ శ్రేణులతో, అలాగే మినహాయింపు తరగతులతో పని చేసే సామర్థ్యాన్ని అందిస్తుంది UnableToEncryptException и UnableToDecryptException, ఇది ఇంటర్ఫేస్ పద్ధతులలో ఉపయోగించాలి Encryptor ఎన్‌కోడింగ్ మరియు డీకోడింగ్ లోపాల విషయంలో వరుసగా.

ప్రధాన ప్రోగ్రామ్ ప్యాకేజీ com.tsarik.programs.gifed స్టాటిక్ మెథడ్‌తో రన్ చేయదగిన ప్రోగ్రామ్ క్లాస్‌ని కలిగి ఉంటుంది main, ప్రోగ్రామ్‌ను అమలు చేయడానికి మిమ్మల్ని అనుమతిస్తుంది; ప్రోగ్రామ్ పారామితులను నిల్వ చేసే తరగతి; మరియు ఇతర తరగతులతో ప్యాకేజీలు.

అల్గోరిథంల అమలు ప్యాకేజీలో ప్రదర్శించబడుతుంది com.tsarik.programs.gifed.gif తరగతులు GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. ఈ రెండు తరగతులు ఇంటర్‌ఫేస్‌ను అమలు చేస్తాయి Encryptor.

GIF ఫార్మాట్ యొక్క నిర్మాణం ఆధారంగా, మీరు ఇమేజ్ ప్యాలెట్‌లో సందేశాన్ని పరిచయం చేయడానికి సాధారణ అల్గోరిథంను సృష్టించవచ్చు:

GIFలో స్టెగానోగ్రఫీ

చిత్రంలో సందేశం యొక్క ఉనికిని గుర్తించడానికి, సందేశం యొక్క ప్రారంభానికి బిట్‌ల యొక్క నిర్దిష్ట శ్రేణిని జోడించడం అవసరం, డీకోడర్ మొదట చదివి ఖచ్చితత్వం కోసం తనిఖీ చేస్తుంది. ఇది సరిపోలకపోతే, చిత్రంలో దాచిన సందేశం లేదని పరిగణించబడుతుంది. తదుపరి మీరు సందేశం యొక్క పొడవును పేర్కొనాలి. అప్పుడు సందేశం యొక్క టెక్స్ట్.

మొత్తం అప్లికేషన్ యొక్క తరగతి రేఖాచిత్రం:

GIFలో స్టెగానోగ్రఫీ

కార్యక్రమం అమలు

మొత్తం ప్రోగ్రామ్ యొక్క అమలును రెండు భాగాలుగా విభజించవచ్చు: ఇంటర్‌ఫేస్ ఎన్‌క్రిప్షన్ మరియు డిక్రిప్షన్ పద్ధతుల అమలు Encryptor, తరగతులలో GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, మరియు వినియోగదారు ఇంటర్‌ఫేస్ అమలు.

తరగతిని పరిగణించండి GIFEncryptorByLSBMethod.

GIFలో స్టెగానోగ్రఫీ

ఖాళీలను firstLSBit и secondLSBit చిత్రం యొక్క ప్రతి బైట్ యొక్క బిట్‌ల సంఖ్యలను కలిగి ఉంటుంది, దీనిలో సందేశాన్ని నమోదు చేయాలి మరియు సందేశాన్ని ఎక్కడ నుండి చదవాలి. ఫీల్డ్ checkSequence పొందుపరిచిన సందేశం యొక్క గుర్తింపును నిర్ధారించడానికి చెక్ బిట్ క్రమాన్ని నిల్వ చేస్తుంది. స్టాటిక్ పద్ధతి getEncryptingFileParameters పేర్కొన్న ఫైల్ యొక్క పారామితులను మరియు సంభావ్య సందేశం యొక్క లక్షణాలను అందిస్తుంది.

పద్ధతి అల్గోరిథం encrypt తరగతి GIFEncryptorByLSBMethod:

GIFలో స్టెగానోగ్రఫీ

మరియు అతని కోడ్:

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

పద్ధతి యొక్క అల్గోరిథం మరియు సోర్స్ కోడ్ decrypt తరగతి GIFEncryptorByLSBMethod:

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

తరగతి అమలు GIFEncryptorByPaletteExtensionMethod ఒకే విధంగా ఉంటుంది, సమాచారాన్ని సేవ్ చేసే/పఠించే విధానం మాత్రమే భిన్నంగా ఉంటుంది.

తరగతిలో MainFrame రేపర్ పద్ధతులు వివరించబడ్డాయి: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), ఇంటర్ఫేస్ పద్ధతుల ఫలితాలను ప్రాసెస్ చేస్తోంది Encryptor మరియు వినియోగదారుతో పరస్పర చర్య చేయడం, అనగా ఫైల్ ఎంపిక డైలాగ్‌ను తెరవడం, దోష సందేశాలను చూపడం మొదలైనవి; అలాగే ఇతర పద్ధతులు: openImage(), చిత్రాన్ని ఎంచుకోవడానికి వినియోగదారుని అనుమతిస్తుంది, exit(), ఇది అప్లికేషన్ నుండి నిష్క్రమిస్తుంది. ఈ పద్ధతులు నుండి పిలుస్తారు Actionయొక్క సంబంధిత మెను అంశాలు. ఈ తరగతి అదనంగా సహాయక పద్ధతులను అమలు చేస్తుంది: createComponents() - ఫారమ్ భాగాల సృష్టి, loadImageFile(File f) — ఫైల్ నుండి ఒక ప్రత్యేక భాగం లోకి చిత్రాన్ని లోడ్ చేయడం. తరగతి అమలు GIFEncryptorByPaletteExtensionMethod తరగతి అమలును పోలి ఉంటుంది GIFEncryptorByLSBMethod, మెసేజ్ బైట్‌లను ప్యాలెట్ నుండి వ్రాయడం మరియు చదివే విధానంలో ప్రధాన వ్యత్యాసం ఉంది.

ప్రోగ్రామ్ ఆపరేషన్

LBS పద్ధతి

ఇలాంటి చిత్రం ఉందని చెప్పండి:

GIFలో స్టెగానోగ్రఫీ

ఈ చిత్రంలో, ప్యాలెట్ 256 రంగులను కలిగి ఉంటుంది (పెయింట్ సేవ్ చేస్తుంది). మొదటి నాలుగు రంగులు: తెలుపు, నలుపు, ఎరుపు, ఆకుపచ్చ. ఇతర రంగులు నలుపు. గ్లోబల్ పాలెట్ బిట్ సీక్వెన్స్ క్రింది విధంగా ఉంటుంది:

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

GIFలో స్టెగానోగ్రఫీ

సందేశం పొందుపరచబడిన తర్వాత, అండర్‌లైన్ చేయబడిన బిట్‌లు సందేశంలోని బిట్‌లతో భర్తీ చేయబడతాయి. ఫలిత చిత్రం దాదాపు అసలు నుండి భిన్నంగా లేదు.

అసలు
పొందుపరిచిన సందేశంతో చిత్రం

GIFలో స్టెగానోగ్రఫీ
GIFలో స్టెగానోగ్రఫీ

పాలెట్ విస్తరణ పద్ధతి

మీరు ఈ పద్ధతిని ఉపయోగించి సందేశాన్ని కలిగి ఉన్న చిత్రాన్ని తెరిచినప్పుడు, మీరు ఈ క్రింది చిత్రాన్ని చూస్తారు:

GIFలో స్టెగానోగ్రఫీ

పూర్తి స్థాయి గూఢచర్య కార్యకలాపాలకు ఈ పద్ధతి పని చేయదని మరియు సందేశం యొక్క అదనపు ఎన్‌క్రిప్షన్ అవసరమవుతుందని స్పష్టమైంది.

యానిమేటెడ్ ఇమేజ్‌లలో ఎన్‌క్రిప్షన్/డిక్రిప్షన్ సాధారణ స్టాటిక్ ఇమేజ్‌ల మాదిరిగానే పనిచేస్తుంది, కానీ యానిమేషన్ విచ్ఛిన్నం కాదు.

ఉపయోగించిన మూలాలు:

డౌన్లోడ్:

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి