LSB steganografisi

Bir zamanlar ben de yazdım hub'daki ilk gönderi. Ve bu yazı çok ilginç bir soruna, yani steganografiye adanmıştı. Elbette o eski konuda önerilen çözüme kelimenin tam anlamıyla steganografi denilemez. Bu sadece dosya formatlarına sahip bir oyun ama yine de oldukça ilginç bir oyun.

Bugün biraz daha derine inip LSB algoritmasına bakmaya çalışacağız. Eğer ilgileniyorsanız, cat'in altına hoş geldiniz. (Kesiğin altında trafik var: yaklaşık bir megabayt.)

Öncelikle kısa bir giriş yapmak gerekiyor. Herkes kriptografinin amacının gizli bilgilerin okunmasını imkansız hale getirmek olduğunu bilir. Elbette kriptografinin kendi uygulamaları vardır ancak veri korumasına yönelik başka bir yaklaşım daha vardır. Bilgiyi şifrelememize gerek yok ama sanki bizde yokmuş gibi davranmalıyız. Steganografinin icat edilmesinin nedeni tam olarak budur. Wikipedia bize "steganografinin (Yunanca στεγανοσ - gizli ve Yunanca γραφω - ben yazıyorum, kelimenin tam anlamıyla "gizli yazı"), aktarım gerçeğini gizli tutarak bilginin gizli aktarımı bilimi olduğunu garanti ediyor.

Elbette hiç kimse kriptografik ve steganografik yöntemleri birleştirmeyi yasaklamaz. Üstelik pratikte bunu yapıyorlar ama bizim görevimiz temelleri anlamak. Wikipedia makalesini dikkatlice incelerseniz, steganografi algoritmalarının sözde içerdiğini göreceksiniz. kapsayıcı ve mesaj. Kap, gizli mesajımızı gizlemeye yardımcı olan herhangi bir bilgidir.

Bizim durumumuzda konteyner BMP formatında bir resim olacaktır. Öncelikle bu dosyanın yapısına bakalım. Dosya 4 bölüme ayrılabilir: dosya başlığı, resim başlığı, palet ve resmin kendisi. Amacımız açısından sadece başlıkta ne yazdığını bilmemiz gerekiyor.

Başlığın ilk iki baytı BM imzasıdır, ardından bayt cinsinden dosya boyutu double word ile yazılır, sonraki 4 byte ayrılmıştır ve sıfır içermelidir ve son olarak başka bir double word, satırın başından itibaren ofseti içerir. Dosyayı görüntünün gerçek baytlarına göre değiştirin. 24 bitlik bir bmp dosyasında her piksel üç BGR baytı ile kodlanır.

Artık görüntüye nasıl ulaşacağımızı biliyoruz, geriye sadece ihtiyacımız olan bilgiyi oraya nasıl yazabileceğimizi anlamak kalıyor. Bunun için LSB yöntemine ihtiyacımız olacak. Yöntemin özü şu şekildedir: Renk kodlamasından sorumlu baytlardaki en az anlamlı bitleri değiştiririz. Diyelim ki gizli mesajımızın bir sonraki baytı 11001011 ise ve görseldeki baytlar...11101100 01001110 01111100 0101100111... ise kodlama şu şekilde görünecektir. Gizli mesaj baytını 4 adet iki bitlik parçaya böleceğiz: 11, 00, 10, 11 ve görüntünün düşük dereceli bitlerini sonuçtaki parçalarla değiştireceğiz: ...11101111 01001100 01111110 0101100111…. Böyle bir değişim genellikle insan gözüyle fark edilmez. Üstelik birçok eski çıkış cihazı bu kadar küçük değişiklikleri bile görüntüleyemeyecektir.

Yalnızca en az önemli olan 2 biti değil, istediğiniz sayıda biti değiştirebileceğiniz açıktır. Şöyle bir model var: Ne kadar çok bit değiştirirsek, o kadar çok bilgiyi gizleyebiliriz ve bu, orijinal görüntüde o kadar fazla girişime neden olur. Örneğin, burada iki resim var:

LSB steganografisi
LSB steganografisi

Tüm çabalarıma rağmen aralarındaki farkı göremedim ama yine de ikinci görselde anlatılan yöntemle Lewis Carroll'un "The Hunting of the Snark" şiiri gizlenmiş. Buraya kadar okuduysanız muhtemelen uygulama hakkında bilgi edinmek ilginizi çekecektir. Oldukça basit ama sizi hemen uyaracağım ki her şey Delphi'de yapılıyor. Bunun iki nedeni var: 1. Delphi'nin iyi bir dil olduğunu düşünüyorum; 2. Bu program, bilgisayarlı görmenin temelleri üzerine bir ders hazırlama sürecinde doğdu ve bu dersi verdiğim adamlar henüz Delphi'den başka bir şey bilmiyorlar. Sözdizimine aşina olmayanlar için bir şeyin açıklanması gerekiyor: shl x, x kadar bit düzeyinde sola kaydırmadır, shr x, x kadar bit düzeyinde sağa kaydırmadır.

Bir dizede saklanan metni kaba yazdığımızı ve alttaki iki baytı değiştirdiğimizi varsayıyoruz:
Kayıt kodu:

i:=1'den uzunluk(str)'a kadar
    başlamak
      l1:=bayt(str[i]) shr 6;
      l2:=byte(str[i]) shl 2; l2:=l2 shr 6;
      l3:=byte(str[i]) shl 4; l3:=l3 shr 6;
      l4:=byte(str[i]) shl 6; l4:=l4 shr 6;
 
      f.ReadBuffer(tmp,1);
      f.Konum:=f.Konum-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Konum:=f.Konum-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Konum:=f.Konum-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Konum:=f.Konum-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    sonunda;

okunacak kod:

for i:=1 - MsgSize yapmak
    başlamak
      f.ReadBuffer(tmp,1);
      l1:=tmp shl 6;
      f.ReadBuffer(tmp,1);
      l2:=tmp shl 6; l2:=l2 shr 2;
      f.ReadBuffer(tmp,1);
      l3:=tmp shl 6; l3:=l3 shr 4;
      f.ReadBuffer(tmp,1);
      l4:=tmp shl 6; l4:=l4 shr 6;
      str:=str+char(l1+l2+l3+l4);
    sonunda;

Gerçekten tembel olanlar için - programa ve kaynak koduna bağlantı.

Teşekkür ederim.

Kaynak: habr.com

Yorum ekle