БтСганография Π² GIF

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠ²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽ.
НС Ρ‚Π°ΠΊ Π΄Π°Π²Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° учился Π² унивСрситСтС, Π±Ρ‹Π»Π° курсовая ΠΏΠΎ дисциплинС Β«ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈΒ». По заданию Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΎΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π²Π½Π΅Π΄Ρ€ΡΡŽΡ‰ΡƒΡŽ сообщСниС Π² Ρ„Π°ΠΉΠ»Ρ‹ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° GIF. РСшил Π΄Π΅Π»Π°Ρ‚ΡŒ Π½Π° Java.

Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ я ΠΎΠΏΠΈΡˆΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ тСорСтичСскиС ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹, Π° Ρ‚Π°ΠΊΠΆΠ΅, ΠΊΠ°ΠΊ создавалась эта нСбольшая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°.

ВСорСтичСская Ρ‡Π°ΡΡ‚ΡŒ

Π€ΠΎΡ€ΠΌΠ°Ρ‚ GIF

GIF (Π°Π½Π³Π». Graphics Interchange Format β€” Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ для ΠΎΠ±ΠΌΠ΅Π½Π° изобраТСниями) β€” Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ хранСния графичСских ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, способСн Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ сТатыС Π΄Π°Π½Π½Ρ‹Π΅ Π±Π΅Π· ΠΏΠΎΡ‚Π΅Ρ€ΠΈ качСства Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ Π΄ΠΎ 256 Ρ†Π²Π΅Ρ‚ΠΎΠ². Π”Π°Π½Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π±Ρ‹Π» Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ Π² 1987 Π³ΠΎΠ΄Ρƒ (GIF87a) Ρ„ΠΈΡ€ΠΌΠΎΠΉ CompuServe для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ растровых ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΏΠΎ сСтям. Π’ 1989-ΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π±Ρ‹Π» ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½ (GIF89a), Π±Ρ‹Π»ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° прозрачности ΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.

Π€Π°ΠΉΠ»Ρ‹ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° GIF ΠΈΠΌΠ΅ΡŽΡ‚ Π±Π»ΠΎΡ‡Π½ΡƒΡŽ структуру. Π”Π°Π½Π½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈ всСгда ΠΈΠΌΠ΅ΡŽΡ‚ Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ (Π»ΠΈΠ±ΠΎ ΠΎΠ½Π° зависит ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ„Π»Π°Π³ΠΎΠ²), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΎΡˆΠΈΠ±ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Π³Π΄Π΅ ΠΊΠ°ΠΊΠΎΠΉ Π±Π»ΠΎΠΊ находится, практичСски Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π³ΠΎ Π½Π΅Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ GIF-изобраТСния Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° GIF89a:

БтСганография Π² GIF

Из всСх Π±Π»ΠΎΠΊΠΎΠ² структуры Π² Π΄Π°Π½Π½ΠΎΠΌ случаС нас Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊ глобальной ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹ ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠ΅ Π·Π° ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρƒ:

  • CT β€” Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ глобальной ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹. Если этот Ρ„Π»Π°Π³ установлСн, Ρ‚ΠΎ сразу послС дСскриптора логичСского экрана Π΄ΠΎΠ»ΠΆΠ½Π° Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ глобальная ΠΏΠ°Π»ΠΈΡ‚Ρ€Π°.
  • Size β€” Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹ ΠΈ число Ρ†Π²Π΅Ρ‚ΠΎΠ² ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ. ЗначСния Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°:

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 (Least Significant Bit, наимСньший Π·Π½Π°Ρ‡Π°Ρ‰ΠΈΠΉ Π±ΠΈΡ‚)
  • ΠœΠ΅Ρ‚ΠΎΠ΄ дополнСния ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹

ΠœΠ΅Ρ‚ΠΎΠ΄ 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 Ρ†Π²Π΅Ρ‚ΠΎΠ² (Ρ‚Π°ΠΊ сохраняСт Paint). ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ†Π²Π΅Ρ‚Π°: Π±Π΅Π»Ρ‹ΠΉ, Ρ‡Π΅Ρ€Π½Ρ‹ΠΉ, красный, Π·Π΅Π»Π΅Π½Ρ‹ΠΉ. ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ†Π²Π΅Ρ‚Π° β€” Ρ‡Π΅Ρ€Π½Ρ‹Π΅. ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π±ΠΈΡ‚ глобальной ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ:

11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000…

БтСганография Π² GIF

ПослС внСдрСния сообщСния ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹Π΅ Π±ΠΈΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ Π±ΠΈΡ‚Π°ΠΌΠΈ ΠΈΠ· сообщСния. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π΅ отличаСтся ΠΎΡ‚ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π°.

ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»
Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ с Π²Π½Π΅Π΄Ρ€Π΅Π½Π½Ρ‹ΠΌ сообщСниСм

БтСганография Π² GIF
БтСганография Π² GIF

ΠœΠ΅Ρ‚ΠΎΠ΄ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹

ΠžΡ‚ΠΊΡ€Ρ‹Π² ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΎ сообщСниС ΠΏΠΎ Π΄Π°Π½Π½ΠΎΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒΡΡ Ρ‚Π°ΠΊΡƒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Ρƒ:

БтСганография Π² GIF

ΠŸΠΎΠ½ΡΡ‚Π½ΠΎΠ΅ Π΄Π΅Π»ΠΎ, Ρ‡Ρ‚ΠΎ для ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΎΠΉ шпионской Π΄Π΅ΡΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ‚Π°ΠΊΠΎΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ ΠΏΠΎΠΉΠ΄Π΅Ρ‚, ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, ΠΌΠΎΠΆΠ΅Ρ‚, Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠΈ сообщСния.

Π¨ΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅/Π΄Π΅ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… изобраТСниях Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΈ Π² ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… статичСских изобраТСниях, ΠΏΡ€ΠΈ этом анимация Π½Π΅ Π½Π°Ρ€ΡƒΡˆΠ°Π΅Ρ‚ΡΡ.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ источники:

Π‘ΠΊΠ°Ρ‡Π°Ρ‚ΡŒ:

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com