GIF ۾ اسٽيگنگرافي

تعارف

پريتم.
گهڻو وقت اڳ نه، جڏهن مان يونيورسٽيءَ ۾ پڙهندو هوس، اتي ”معلومات جي حفاظت جا سافٽ ويئر طريقا“ نظم و ضبط جو ڪم هو. تفويض اسان کي هڪ پروگرام ٺاهڻ جي ضرورت آهي جيڪا GIF فائلن ۾ هڪ پيغام شامل ڪري. مون ان کي جاوا ۾ ڪرڻ جو فيصلو ڪيو.

هن آرٽيڪل ۾ آئون ڪجهه نظرياتي نقطا بيان ڪندس، انهي سان گڏ هي ننڍڙو پروگرام ڪيئن ٺاهيو ويو.

نظرياتي حصو

GIF فارميٽ

GIF (گرافڪس انٽرچينج فارميٽ - تصويرن جي تبادلي لاءِ هڪ فارميٽ) گرافڪ تصويرن کي محفوظ ڪرڻ لاءِ هڪ فارميٽ آهي، جيڪا 256 رنگن جي فارميٽ ۾ معيار جي نقصان کان سواءِ ڪمپريس ٿيل ڊيٽا کي محفوظ ڪرڻ جي قابل آهي. هي فارميٽ 1987 ۾ ترقي ڪئي وئي (GIF87a) CompuServe پاران نيٽ ورڪ تي راسٽر تصويرون منتقل ڪرڻ لاءِ. 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 جو طريقو - steganography جو هڪ عام طريقو. اهو ڪنٽينر ۾ آخري اهم بٽ کي تبديل ڪرڻ تي مشتمل آهي (اسان جي صورت ۾، گلوبل پيلٽ بائيٽ) پوشیدہ پيغام جي بٽ سان.

پروگرام هن طريقي جي حصي طور عالمي پيليٽ بائيٽ ۾ آخري ٻه بٽ استعمال ڪندو. هن جو مطلب آهي ته 24-bit تصوير لاءِ، جتي رنگ پيلٽ ٽي بائيٽ آهن ڳاڙهي، نيري ۽ سائي لاءِ، ان ۾ هڪ پيغام شامل ڪرڻ کان پوءِ، هر رنگ جو حصو وڌ ۾ وڌ 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، بنيادي فرق اهو آهي ته پيغام جي بائيٽس کي پيٽ مان لکجي ۽ پڙهيا وڃن.

پروگرام آپريشن

ايل بي ايس جو طريقو

اچو ته چوندا آهن ته هن وانگر هڪ تصوير آهي:

GIF ۾ اسٽيگنگرافي

هن تصوير ۾، پيلٽ 256 رنگن تي مشتمل آهي (جيئن ته رنگ محفوظ ڪري ٿو). پهرين چار رنگ آهن: اڇو، ڪارو، ڳاڙهو، سائو. ٻيا رنگ ڪارو آهن. عالمي پيلٽ بٽ جي ترتيب هن ريت هوندي:

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

GIF ۾ اسٽيگنگرافي

هڪ دفعو پيغام کي شامل ڪيو ويندو، هيٺ ڏنل بٽ پيغام جي بٽس سان تبديل ڪيا ويندا. نتيجو واري تصوير اصل کان تقريبا مختلف ناهي.

اصل
تصوير شامل ٿيل پيغام سان

GIF ۾ اسٽيگنگرافي
GIF ۾ اسٽيگنگرافي

پيٽ جي توسيع جو طريقو

جڏهن توهان هڪ تصوير کوليو جنهن ۾ هن طريقي سان پيغام شامل آهي، توهان کي هيٺ ڏنل تصوير نظر ايندي:

GIF ۾ اسٽيگنگرافي

اهو واضح آهي ته اهو طريقو مڪمل جاسوسي سرگرمين لاء ڪم نه ڪندو، ۽ پيغام جي اضافي انڪرپشن جي ضرورت ٿي سگھي ٿي.

متحرڪ تصويرن ۾ انڪرپشن/ڊيڪرپشن ڪم ڪندو آهي جيئن باقاعده جامد تصويرن ۾، پر انيميشن ٽوڙيو ناهي.

ذريعن جو استعمال:

ڊائون لوڊ

جو ذريعو: www.habr.com

تبصرو شامل ڪريو