Su ulozene postupne do najmenej dolezitych bitov.
Funguje to tak, ze lubovolny subor urceny na vnimanie clovekom (obrazok, zvuk) ma data v niecom ulozene, pricom clovek nerozozna (napr. v ciernobielej palete s 256 farbami) 2 susedne stupne (sedej). Potom by bola cierna zakodovana ako 0000 0000. Ak chcete do tohto bajtu steganograficky vlozit bit „y“ (0 alebo 1), tak z toho vznikne 0000 000y. Pointa je v tom, ze sa predpoklada unikatnost fotky a sama fotka ma tieto bity takmer nahodne, preto sa da tazko dokazat, ze tam je nieco skryte.
Teraz vyvratim este cast toho, co som povedal: bity nie su ulozene postupne, to by vedel kazdy zistit – preto sa zaviedlo heslo, ktore urcuje poradie jednotlivych bitov. Kedze do obrazku by sa takto dalo ulozit len malo dat (x*y*c bitov, kde x,y su rozmery obrazka a c je pocet kanalov (obycajne 3 – RGB) ), zacali ludia pisat nielen do posledneho bitu z bajtu, ale do niekolko poslednych bitov. Dalej pri steganografickom ukryvani zacala do suborov ukladat aj hlavicka a kontrolny sucet, ktore uz mozu prezradit, ze je v obrazku nieco skryte. Schvalne mozete svojmu programu na steganografiu podstrcit fotku, v ktorej nie je nic ukryte – niektore programy sa ani nepytaju na heslo a hned prezradia, ze tam nie je nic, co je ich velka nevyhoda.
Predpokladam, ze zaklad zistenia, ci je v obrazku nieco skryte je u modernych programov v analyze JPEGu – tento format obrazku totiz nie je urceny na bezstratove ukladanie jednotlivych bitov, preto by som osobne radsej odporucal bitmapy a vlastny program (to pre tych, ktori to zvladnu napisat).
Zakladny predpoklad popretia ulozenia dat (ktoreho som si v clanku nevsimol) je unikatnost toho obrazku alebo hudby – povodny obrazok / hudbu je treba nenavratne znicit a nepouzivat verejne dostupne a na PC upravovane alebo vytvorene obrazky / hudbu. Najlepsie su prave uz od vyfotenia zasumene fotky (z fotaku, ktory produkuje len take fotky), kde sa mierna zmena sumu neda lahko rozlisit.
Každá metoda to dělá jinak. Jedna starší a oblíbená:
Máte obrázek v .PNG nebo něčem jiném, co umí bezeztrátově barvy ve 24 pixelech.
Vyberete si heslo – číslo.
Poskytnete datový soubor, který chcete ukrýt. To je sled bitů.
Nyní pomocí hesla vygenerujete fraktál (třebas Mandelbrotovu množinu) stejné velikosti jako je původní obrázek. Tento fraktál si připravíte na black and white obrázek (budeme mu říkat šablona). A začnete kódovat. Vytváříte nový, opět black and white obrázek (budeme mu říkat filtr), který generujete tak, že:
1. jdete na první pixel filtru a šablony a na první bit kódované zprávy
2. podíváte se do šablony, jak je obarven tento pixel
3. pokud je bílý, pak do filtru vložíme náhodnou barvu (černá nebo bílá)
4. pokud je černý, pak do něj vložíme aktuální bit kódované zprávy a posuneme se na další bit
5. přesuneme se na další pixel filtru a šablony a opakujeme
Výsledkem je filtr, černobílý obrázek, zdánlivě náhodný.
A filtr teď zakódujeme se vstupním obrázkem. Půjdeme pixel po pixelu. Budeme upravovat pixel původního obrázku tak, aby součet RGB složek byl sudý nebo lichý podle barvy odpovídajícího pixelu ve filtru. Tudíž filtr nám říká, zda má pixel být sudý nebo lichý. Pokud je dejme tomu v obrázku pixel barvy R=255, G=0, B=255 (fialová) a podle filtru má být součet sudý, pak neděláme nic (255+0+255 už sudé je). Pokud by měl být lichý, pak náhodně upravíme jednu ze složek náhodným směrem o 1. Tedy na R=254,G=0,B=255 nebo R=255,G=1,B=255 nebo R=255,G=0,B=254. A tím získáme zakódovaný obrázek, kde se barva každého pixelu liší od původního obrázku jen velmi nepatrně.
A teď jdeme dekódovat. Nejprve si spočítáme filtr. To je snadné, ve vstupním obrázku jen spočítáme součty RGB složek a filtr bude mít daný pixel bílý nebo černý podle toho, zda je součet sudý nebo lichý. Takže máme filtr, který vypadá jako náhodný šum.
Nyní si spočítáme šablonu. Úplně stejným způsobem jako při kódování – spočítáme fraktál podle zadaného hesla. Tak máme šablonu. Nyní položíme šablonu na filtr, čímž se dozvíme, které bity filtru jsou jen náhodné hodnoty a které jsou platné bity původní zprávy. A ty platné bity si sestavíme zpět do bajtů a do původní zprávy.
Při této metodě se používají fraktály, které generují pokud možno náhodné šablony nebo alespoň dostatečně náhodné a řídké. Někdy se to komplikuje tím, že se bity původní zprávy nezapisují do filtru po řádcích, ale nějakým pseudonáhodným způsobem (poskakuje modulo 11 apod.)
Základ této metody je tedy v tom, že si připravím filtr. Obrázek stejné velikosti jako ten původní, ale jen s 1 bitovou hloubkou (černo bílý). Tento jeden bit pak zakóduji do původního obrázku jako sudý/lichý součet RGB složek.
Fraktál (šablona) je jen krok, jak do filtru zanést náhodnost (aby nebyla zakódovaná data ihned patrná) a zabránit dekódování informace bez hesla. Metoda funguje výborně z pohledu „ochrany“ zprávy (což se ovšem dalo řešit tím, že zakóduji již zašifrovanou zprávu), ale je naopak snadno odhalitelná (což je z pohledu steganografie problém). Je to tím, že přidaný šum je sice náhodný, ale tak nějak nepatřičný. Pokud máte kvalitní vstupní obrázek, pak již při povrchní analýze poznáte, že se barva pixelů liší (to ještě není problém), ovšem bezdůvodně (proč je obrázek vůbec zašuměný?) Obzvláště patrné je to na obrázcích s malým počtem barev a velkými jednobarevnými plochami (histogram barev je prevít). Ovšem třebas na fotkách z mobilu to poznat rozumně nejde :-)
Metoda se dá vylepšit tím, že se barva pixelu neposouvá zcela náhodně a jen o jedničku, ale udělá se histogram barev v okolí pixelu a vybere se některá z těchto barev. Tím se změna barvy na histogramu neprojeví. Další komplikace je nepracovat po pixelech ale po skupině. Kupříkladu nepracovat s tím, zda součet RGB je sudý nebo lichý, ale zda je jeho párovost shodná s předchozím pixelem. Nebo počítat součet RGB složek z matice 3×3 pixely, třebas i s vyloučením centrálního pixelu. Vše tohle zkomplikuje získání filtru a zároveň to dává více možností jak měnit barvu pixelů a tudít umožní snadněji a lépe udržet „statistické charakteristiky“ v „neodhalitelných“ hodnotách. Další variace je použít šablonu i při úpravách pixelů v obrázků tak, aby se sudá/lichá zpracovávalo jen pro pixely nesoucí informaci. Pixely, u kterých pak nezáleží na jejich stavu, poslouží k dalším hrátkám se statistikou – samy informaci nenesou, takže jim můžu dát jakoukoliv barvu, která se mi bude hodit.
V případě jiných formátů obrázků fungují zcela odlišné metody. Zajímavou kapitolou jsou ztrátové formáty jako je .jpeg. Tam pochopitelně tato metoda aplikovat nejde.
Zaujímavé.
Ale vyplýva z toho, že akákoľvek grafická zmena obrázku ukrytú správu znehodnotí (no, možno má nejaké redundantné dáta na obnovu, ale myslím že také zvýšenie kontrastu alebo doostrenie to nenávratne odpáli, nehovoriac o zmenšení).
Mne sa ale zdá, že som kedysi čítal o spôsobe, ktorý prežije dokonca odfotenie z obrazovky či oscanovanie, je to možné?
To, co máte na mysli, je pravděpodobně watermarking. Tam ale není smysl zprávu utajit (a watermarky se většinou dají snadno zjistit), ale naopak zaručit, že se ani po úpravě neztratí. Používají to třeba filmové korporace pro označování konkrétních pásek, aby zjistily, kdo ten film na YouTube nahrál
Pekne popsano, diky za prehled. Jen me napadlo, jestli neni lepsi misto fraktalu, ktery neni nahodny (deterministicky chaos :-) pouzit nejaky hodne dobry generator cisel s velkou entropii a na zaklade jeho vystupu vygenerovat sablonu? Jak fraktal, tak i generator maji nejaky seed (u Mandelbrotky stred+zvetseni+pocet iteraci, u generatoru zalezi na jeho konstrukci).
Nejedná se o generátor náhodných čísel, ale o generátor čísel s vysokou entropií na základě hesla=seedu. Pro generování zcela náhodných šísel se pak používá nějaká proměnná hodnota, třeba hodnota z časovače (známe Randomize(timer); ze starého pascalu). Pokud se generátoru pseudonáhodných čísel přiřadí stejný výchozí stav, je výsledná řada dostatečně náhodná=má vysokou entropii, ale zároveň je deterministická.
Ceho tim ale dosahnete, kdyz misto fraktalu pouzijete deterministicky, tedy nikoliv „hodne dobry“ generator nahodnych cisel? Jenom nahradite jeden deterministicky proces (fraktal) jinym (pseudonahodny generator) a prijemce nebude muset znat heslo, ale seed, tedy jine heslo. Jestli to spravne chapu, tak treba sum ze sumove diody je vam ve steganografii na dve veci.
Ano, čistě náhodná čísla k ničemu nejsou, jde o to vygenerovat nějakou deterministickou masku, která určuje kde co bude uložené, varianta „lepšího“ hesla.
Pokud je samotný steganografický algoritmus utajený, pak v podstatě nelze zjistit zda jsou nějaká data do obrázku „přimíchána“ a o to jde. Algoritmus může „pseoudonáhodně“ přezkakovat bity (dopředně nebo i zpetně), uložená data lze třeba dodatečně šifrovat, fantazii se meze nekladou. Výsledkem je, že jek a pouze ten kdo ví, že médium (obrázek) něco ukrývá a zároveň zná správné heslo=má klíč může data přečíst.
Pokud nezadáte správné heslo/seed/klíč, prostě nebude správná maska, můžete dostat třeba nesmyslná data a to i v případě, že obrázek žádnou informaci neukrývá, to je opět věcí návrhu algoritmu
To ale vyzaduje zatracene dobry pseudonahodny generator s obrovskou mnozinou moznych hodnot. Nejsem si jist, jestli tak velke mnoziny nedosahnete snaze pomoci fraktalu. Pokud mnozina hodnot neni dostatecne velka a je znam algoritmus, kterym data byla do obrazku vlozena, projedou vam na slusnem pocitaci vsechny mozne kombinace v realne dostupnem case a pak se staci podivat, jestli neco nevypada na znamy format dat. Tedy treba kryptovani s ASCII armor je blby napad, protoze to pozna i cvicena opice. Je treba pouzit neco, co vypada naprosto binarne, s hodnotami bajtu 0–255, coz ASCII armor zrovna neni. Lze neco takoveho dostat treba z GPG?
Jakykoliv pseudonahodny generator lze realizovat pomoci nekolika bitovych operaci – bitova rotace, bitove or, xor… v algoritmu, na ktery byla moje prvni reakce, je potreba vygenerovat masku, pripadne vygenerovat sum pokud obrazek obsahuje znatelne jednobarevne plochy. Tento generator informaci nesifruje, ale schovava do šumu, vlastni data lze dodatecne sifrovat pred vlozenim do media. Jen pripomenu veticku zezhora, steganografie je prolomena ve chvili, kdy je prokazan fakt, ze medium skrytou informaci nese – coz nutne neznamena, ze informace musi byt citelna.
Velmi pekne napisane, nieco podobne vo velmi zjednodusenej forme som skusal. Zobrala sa fotka vo formate .bmp (JEDNODUCHE!!!) a sprava a prvy bit spravy s prvym pixelom, druhy s druhym… pricom ak bol bit spravy 1 tak sa nastavil pixel tak aby farbu vyjadrovalo neparne cislo a ak 0 tak parne(jednoducho: color – color mod 2 + bit) zmena bola minimalna, samozrejme na odhalenie staci kazdy pixel mod 2 a hodit to do postupnosti bitov a mohli ste precitat spravu… A samozrejme koniec spravy oznacoval znakom #0 :D Samozrejme JPEG by spravu poskodil…