Orjinal Steganografi mantığı biraz daha farklı çalışsa da, bu uygulamada tamamen kendi yöntemlerimi uyguladığımı söylemeliyim. Bunu açıklamamın nedeni, aşağıda anlatılan bilgiler başka Steganografi uygulamaları için geçerli olmayabilir. Ve elimden geldiğince arkada neler döndüğünü ayrıntılı olarak anlatmaya çalışacağım.
Gizleme işlemini anlamak için ilk başta bir resmin nasıl oluştuğunu bilmek gerekir. Bir resim, genişiği x yüksekliği kadar pixelden oluşur. Buraya kadar çoğu kişi bilir. Ancak asıl olay bir pixeldeki rengin nasıl tutulduğudur. Günümüzde, dijital ortamdaki genel amaçla kullanılan tüm resimler 24 bittir, yani bir pixel 24 bitten oluşuyor. Bu da bir pixel 224 kadar farklı değer, yani renk tonu alabilir demek.
Bir pixeldeki renk 3 kanaldan oluşur. Bu kanallar lisede fizik dersinde gördüğünüz kırmızı, yeşil ve mavidir. Tüm renk tonları ise sadece bu 3 rengin farklı orandaki karışımlarıyla oluşur. Pixeldeki renk için de ifade edilirken kullanılan değer, bu 3 kanalın kombinasyonudur. Peki nasıl olur derseniz; buradan sonrasını anlamak için sayı sistemlerini biraz bilmek gerekmektedir. Rengi ifade eden değer aslında 3 kanalı ayrı ayrı ifade eden değerlerin bit tabanlı kaydırmalarla kombine edilmiş halidir. Her kanalı ifade eden değer 8 bitten oluşur ve bu kanallar kaydırılarak yan yana yazıldığında 24 bit olmuş olur. Bu arada bahsedilen bitten kasıt ikilik düzendeki her bir basamaktır.
Kırmızı renk 16 bit kaydırılır, yeşil renk 8 bit kaydırılır ve mavi renk ise hiç kaydırılmaz. Ardından bu değerler toplanır ve ortaya pixelin tüm kanalları gösteren kombine edilmiş tek bir değer ortaya çıkar.
Bir pixeldeki değeri bit tabanlı gösterecek olursak;
| Pixel [ 24 Bit ] | |||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Kırmızı [ 8 Bit ] | Yeşil [ 8 Bit ] | Mavi [ 8 Bit ] | |||||||||||||||||||||
| 223 | 222 | 221 | 220 | 219 | 218 | 217 | 216 | 215 | 214 | 213 | 212 | 211 | 210 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
Bir de pixeli ifade eden sayının pixeli nasıl etkilediğini görmek amacıyla birkaç örneğe bakalım;
| Değer (Desimal) | Kırmızı | Yeşil | Mavi | Renk | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16711680 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Kırmızı |
| 65280 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Yeşil |
| 255 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | Mavi |
| 16711935 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | Magenta |
| 3253652 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | Ara Bir Renk |
Tek bir kanal için konuşursak, 8 bitten oluştuğunu ve 0 - 255 arası değer aldığını gördük. Artık Msb (Most Significant Bit) ve Lsb (Least Significant Bit) ten bahsedebiliriz. Bunların anlamı En Etkili ve En Etkisiz Bittir. En soldaki bite Msb ve en sağdaki bite Lsb denir. Daha anlaşılır şekilde söylersek; bit düzeyinde sağa tarafa gittikçe bitin etkisi azalır ve sola gittikçede artar.
Burada anlatılmak istenen şudur; en sağdaki biti değiştirmek (1 ise 0 veya 0 ise 1 yapmak) renk tonunda gözle görülmeyecek kadar küçük bir ton değişimi sağlar. Benzer şekilde en soldaki biti değiştiriseniz, renk bariz bir şekilde değişir. Artık yavaş yavaş Steganografi'yi anlayabiliriz.
Uygulama yazılacak bilgiyi ilk önce binary paketlere ayırır. Yani bilgi her ne olursa olsun tamamını sadece "1" ve "0" lardan oluşan uzun bir diziye çevirir. Ardından sırayla her pixelin her kanalının Lsb'sine, binarye çevrilen bilginin bitlerinden bir tanesini yazar. Artık Steganografinin ne yaptığını anlıyoruz. Diyelimki yazılacak bilgi uzun, tüm pixel kanallarının ilk bitlerine veri yazıldı ve hala yazılması gereken bilgi var. Bu durumda kanalların 2. bitine geçer ve bilgiyi yazmaya devam eder. Hala bitmediyse 3,4,5 diye tüm bitler dolana kadar devam eder. Ancak yazma işleminde her 1 bit sola geçildiğinde, resimde daha çok gözle görülür bozulmalar olmaya başlar. Örneğin 8. bite gelinmişse Msb ler de bozulacağından resim tamamen bozulabilir. Bu durumda resim karıncalı gözükmeye başlayacaktır.
Pixellere bilgiyi yazarken renk bozulumunu insan gözüne daha az belli etmek için etkili bir metodum vardır. O da bilgileri homojen şekilde yazmaktır. Bu demek oluyorki, bilgiyi pixellere sırayla değil, belli bir algoritmayla seyrek şekilde yazmaktır. Örnek vermek gerekirse, ilk etapta arı peteği benzeri bir görünümde olacak şekilde pixellere atlaya atlaya bilgi yazılır. Doku tamamlandıktan sonra biraz daha sık bir dokuyla devam eder ve daha sık. Yer kalmadıktan sonra, artık bir üst bite geçilebilir.
Bu yöntem olmasaydı, örneğin bilgi gözle görülecek kadar bozulmaya neden olacak büyüklükte ve bilgi sonu resmin ortasına denk geliyorsa, sonuç çıktısında, resmin yarısı bozuk yarısı düzgün görünecekti. Ancak bu yöntem sayesinde bozulma resme homojen şekilde dağılmış oluyor. Aynı şekilde bozulmamış renklerde resme dağılacağından resim daha net gözükmektedir.
Yolcu olan bilgi, konağa olduğu gibi yazılmaya başlanmıyor tabi ki. Aksi halde çözme sırasında, ugyulama çözülümün nasıl olacağını bilemeyecektir. Çünkü yazılan bilgiler çeşitlidir. Örneğin; dosya ise dosyanın ismi, formatı gibi bilgiler gerekmektedir, veya metin ise sıkıştırıldı mı yoksa normal mi, veya en basidinden yolcu olan bilgi ne kadar uzundur, yani resmin neresine kadar okunması gerekir gibi bilgileri de konağa yazmalı ki, çözülüm sırasında çözülümün nasıl olacağı anlaşılsın.
Tüm bu parametre ve bilgilerin birleşimine kısaca başlık diyeceğim. Bu durumda, yazılacak yolcunun başına başlık bilgisini de ekleyerek, yolcunun bu son halini artık doğruca yazabiliriz.
Başlığın en başına kendi dijital imzamı eklemekteyim. Böylece çözülüm sırasında, daha başlık bilgisi okunurken, konak doğru mu, içerisinde bilgi var mı, alplab.dev Steganografi uygulamasıyla mı gizlenmiş yada konak bozulmuş mu gibi sorulara hızlı bir cevap alabilirim. Aksi halde çözümleme işlemi, gizlenmiş bilgi olmayan bir resmi de sanki bilgi varmış gibi okuyarak, gerçekte olmayan bozuk bir dosya üretecektir. Diğer bir yandan imza; gereksiz işlemleri önleyecek bir performans tasarrufu sağlamaktadır.
İmzanın arkasına yolcunun ne kadar uzun olduğunu söyleyen sayı eklenir. Böylece çözümleyici nerede duracağını bilecektir. Bu arada uzunluğu belirten sayının bayt paketinin tepesindeki 2 bitini de; metin, dosya gibi değişkenlerin parametrik bilgilerini yazmak için kullanmaktayım. Neden böyle yaptığımı anlamak için, binary olan bir verinin bayt paketlerini bilmek gerekmektedir ve ben 2 bit için ayrı bir bayt (8 bit) harcamak istemedim. Yolcu uzunluğuna, 3 baytlık kısım ayrımaktayım ve 2 biti kullanıldığından dolayı geriye 22 bit kalmakta, bu da en fazla 4.194~ Kb lık yolcu yazılabilineceğini gösteriyor, ancak sunucu trafiğini korumak amaçlı en fazla 250 Kb'a izin vermekteyim. Daha ayrıntılı bilgi için; Steganografi › Sınırlamalar
Standart başlık burada bitmektedir, ancak yazılacak veri bir dosyaysa, dosyanın ismini ve dosyanın isminin uzunluğunu tutması için başlık genişletilir. Dosya isminin uzunluğu tutması için başlığa bir bayt daha eklenir ve buna opsiyonel bayt diyorum. Bu noktadan sonra dosya ismi ne kadar uzunsa oraya kadar okunacak ve ardından asıl dosya içeriğini okumaya başlayacaktır.
Kullandığım başlığı bit tabanlı olarak tabloda göstermek gerekirse;
| İmza | Mod Parametleri | Dosya Uzunluğu | Opsiyonel Bayt | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B | B | ||||||||||||||
| B | B | B | B | B | B | B | B | B | B | B | B | B | B | B | |||||||||
| 13 Bayt | 3 Bayt (2 bit) + (6 bit + 2 bayt) | 1 Bayt | |||||||||||||||||||||
* B=Bayt, 0=Bit ifade etmektedir.
Yani kısaca yazılacak bilginin başına, nasıl okunduğunu anlatan 16 + 1 opsiyonel baytlık bir başlık bilgisi de eklenir ve o şekilde yazılır.
Hesaplamak oldukça basittir. Hesap şöyle yapılır; "genişlik x yükseklik x 3 (kanal) - 16 (Başlık bilgisi)". Eğer yazılacak bilgi bir dosya ise hesabın sonuna; "- 1 (dosya ismi uzunluğunu tutan bayt) - dosya ismi uzunluğu" ekleyebilirsiniz. Bu size tam olarak konağın en fazla kaç baytlık veri alacağını söyler. Ancak bu kadar veri aldıktan sonra konak tamamen anlaşılmaz olacaktır. Net bir görüntü için kapasiteyi hesaplarken pixellerin bit kullanımını da hesaba sokarsak, formulun pixel sayısını veren kısmına "bit/maksimum bit" eklenebilir. Maksimum bit 8'dir, bu durumda eklenecek kısım "bit/8"'dir. Net bir görüntü için de bit en fazla 3 olmalıdır, çünkü daha fazlası görüntüyü belli olacak şekilde bozmaya başlar. Dolayısıyla eklenecek kısım artık "3/8". Eğer formulun son halini merak ediyor iseniz;
(genislik x yükseklik x 3) x 3/8 - 16 - {Dosya ise | 1 + dosya ismi uzunluğu}
Bu formül bize ideal oranda ve bozulum olmadan sığacak bilgi kapasitesini verir.
Bir örnek yapacak olursak; 600x800 olan bir konağa "dosya.txt" metin belgesini yazacağız, ve konağı bozmadan metin belgesinin boyutunun en fazla ne olabileceğini merak ediyoruz. Hesap şudur; (800x600x3x3)/8-16-1-9 = 539974; bu da 540~ Kb lık bir veri yapar ki bu konağı bozmadan hiç fena değil.
Hazır bit kullanımından bahsetmişken, Steganografi uygulamamın kullanıma göre otomatik olarak yorumunun tablosu da şudur;
| Bit | Yorum | Maks % Oranında Bozulum |
|---|---|---|
| 1 | En İyi Kalite | 2 |
| 2 | Yüksek Kalite | 6 |
| 3 | İdeal Kalite | 14 |
| 4 | Orta Kalite | 25 |
| 5 | Düşük Kalite | 39 |
| 6 | Ciddi Renk Kaybı | 56 |
| 7 | Ciddi Renk Kaybı | 77 |
| 8 | Görsel Karıncalı ve Anlaşılmaz | 100 |
* Hazır bu kadar bilgi vermişken % bozulumunun formülü de şudur; ( bit2 x 100 ) / 64
Eğer bu sayfayı tamamen okuduysanız, dosya seçip ardından "Gizle" veya "Çöz" düğmesine tıklandığınızda aslında arka tarafta neler döndüğünün artık bilincindesiniz.