Sandra Lewandowska

Witaj w mojej przestrzeni!

St3g0 v.0.3

O aplikacji

Aplikacja St3g0 v.0.3 służy do steganografii plików graficznych i jest częścią programu pisanego w ramach studiów.

Więcej szczegółów na temat algorytmu LSB we wpisie: https://sandralewandowska.pl/steganografia/383/lsb/

Po wybraniu przycisku Next zostaje wywołana metoda validate() danego kontrolera. Jeśli brakuje pola lub jest uzupełnione nieprawidłowo, wyświetlony zostaje komunikat o błędzie a przejście do kolejnego kroku jest blokowane.

Użyte technologie/narzędzia/biblioteki:

JavaFX 8 – odpowiada za graficzny interfejs aplikacji z pomocą Gluon Scene Builder,
Java 8 – jako minimalny wymóg do współpracy z JavaFX 8,
Maven – do pobrania bibliotek wymaganych w projekcie,
Google Guice – użycie adnotacji @Inject dla pól pozwala otrzymać udostępniony obiekt WindowData. Ułatwia to przedstawienie poszczególnych kroków formularza na osobnych widokach,
slf4j z log4j – wyświetlanie/zapis logów.

Prezentację aplikacji można zobaczyć na poniższych filmach.
W pierwszym wideo ukrywaną informacją jest plik graficzny, a w drugim zwykły tekst.

Link do kodu: Kod – https://github.com/sanlew/st3g0

Uruchomienie aplikacji

1. mvn clean install -U
2. mvn jfx:jar
3. cd target/jfx/app
4. java -jar stego-0.0.1-SNAPSHOT-jfx.jar

Metoda modyfikacji kolorów indeksowanych

Akrykuł wyjaśnia budowę pliku GIF i przykład steganografii metodą modyfikacji kolorów indeksowanych.

Obraz w formacie GIF jest plikiem indeksowanym. Oznacza to, że piksele nie zawierają bezpośrednio informacji o kolorach RGB, tylko numer indeksu do tablicy,
w której ten kolor się znajduje. Wiadomość zostaje ukryta według wcześniejszego schematu algorytmem LSB, jednak zmianie nie ulegają wartości składowe danego koloru, ale numery indeksów. Zmiana tylko jednego najmłodszego bitu powoduje przesunięcie wartości numeru indeksu co najwyżej o 1. Z tego powodu
obok siebie w tablicy kolorów powinny występować barwy o podobnych własnościach, aby ich podmiana nie była zauważalna. Dodatkowo informacje o pikselach są kompresowane metodą słownikową LZW (Lempel-Ziv-Welch), co pozwala na uzyskanie mniejszego rozmiaru pliku w formacie GIF, jednak nieco komplikuje sposób wydobycia informacji o numerach indeksów w pikselach. Powyższe czynniki wpływają na konieczność wstępnego przetworzenia pliku przed zastosowaniem algorytmu LSB.

Obraz GIF przekształcony w tablice bajtów składa się z kilku bloków informacji. Na potrzeby ukrycia informacji konieczne jest wydobycie indeksowanej tablicy kolorów oraz samych danych dotyczących indeksu w danym pikselu. Stałe elementy w budowie formatu pozwalają łatwo wyodrębnić potrzebne informacje z obrazu w formie tablicy bajtów.

Plik rozpoczyna się blokiem nagłówkowym. Pierwsze 6 bajtów zawsze określa format pliku, na przykład GIF89a. W programie sprawdzenie formatu pliku odbywa się poprzez odczytanie typu pliku mimetype,np:

String mimetype = new MimetypesFileTypeMap().getContentType(inputFile)

Istotny jest 11 bajt z kolei (indeks 10), który zawiera 4 pola spakowanych danych. Najbardziej znaczący bit to informacja czy w pliku występuje globalna tabela kolorów. Ustawienie tej flagi na 1 potwierdza, że obraz zawiera indeksowaną tablicę kolorów globalnych. Przydatną informację zawierają również 3 ostatnie bity w tym bloku, określające rozmiar tablicy kolorów. Jeśli wartość tego pola jest równa N, to liczba wpisów w globalnej tablicy kolorów będzie wynosić $2^{(N + 1)}$. Tablica kolorów w formacie GIF może mieć więc maksymalnie 256 kolorów, a jej rozmiar to $3*2^{(N + 1)}$, ponieważ każdy kolor zapisany jest za pomocą trzech składowych RGB.

Tablica kolorów w obrazie GIF nie jest domyślnie w żaden sposób sortowana. Kolory można by uporządkować tak, aby obok siebie znajdowały się podobne odcienie z palety, jednak oko ludzkie jest bardziej czułe na różnicę w jasności pikseli niż na zmianę koloru, więc w projekcie tablica została posortowana według wzoru na relatywną luminancję w przestrzeni kolorów RGB:
luminance = (r ∗ 0.2126f + g ∗ 0.7152f + b ∗ 0.0722f )1

Po lewej grafika stworzona na podstawie tablicy kolorów wczytanej z pliku, po prawej kolejność barw w posortowanej tablicy

Po lewej grafika stworzona na podstawie tablicy kolorów wczytanej
z pliku, po prawej kolejność barw w posortowanej tablicy

Dzięki sortowaniu globalnej tablicy kolorów podmiana barw na sąsiednie przy użyciu LSB w tablicy indeksów nie jest tak zauważalna.

Po posortowaniu tablicy kolorów kolej na podmianę indeksów w pikselach obrazu. Po wczytaniu tablicy kolorów przesunięcie numeru indeksu danych wynosi $12 + 3*2^{(N + 1)}$. Kolejny może być opcjonalny blok sterowania rozszerzeniami graficznymi. Łatwo rozpoznać czy wystęþuje, ponieważ zawsze rozpoczyna się taką samą parą bajtów w notacji heksadecymalnej 21 oraz F9, czyli $33_{(10)}$ i $-7_{(10)}$. Jeśli blok jest obecny, dodajemy do przesunięcia kolejne 8 bajtów i przechodzimy do bloku danych obrazu, który standardowo zaczyna się od bajtu $2C_{(16)}$, czyli $44_{(10)}$. Odczytanie danych dotyczących szerokości i wysokości obrazu pomoże upewnić się, że do tej pory dane pliku były odczytane prawidłowo. Jeśli obraz składa się z ruchomej sekwencji, mogą wystąpić lokalne tablice kolorów, zbudowane podobnie jak główna tablica kolorów.

Następny blok zawiera w końcu szukaną informację, czyli tablicę z indeksami kolorów pikseli. Dla dużych obrazów kolejne wartości pikseli zajęłyby dużo miejsca, więc dane są skompresowane algorytmem LZW. W skrócie LZW tworzy pomocniczy słownik, w którym występującym w obrazie wartościom przypisuje się dodatkowe kody. W przypadku gdy użyta jest maksymalna ilość barw, czyli 256 – kody poszczególnych kolorów od 0 do 255 zostają przypisane w słowniku tak jak w tablicy kolorów. Jako kolejny element z kodem 256 umieszczony jest znacznik „clear code”, który informuje o rozpoczęciu kolejnej sekwencji danych.
Następny kod 257 zarezerwowany jest jako informacja o końcu pliku. Dane o pik- selach podzielone są na bloki o wielkości z zakresu 0-255. Rozmiar każdego bloku jest określony w pierwszym wczytanym bajcie danej sekwencji. Dalsze dodawanie kodów do słownika opiera się na łączeniu sekwencji poprzednich bajtów i nowowczytanego. Jeśli ciąg danych powstały w ten sposób nie ma przydzielonego swojego kodu, zostaje dodany do słownika z kolejną wartością zapisaną jako kod. Po przeprowadzeniu dekompresji metodą LZW otrzymujemy tablicę bajtów z indeksami kolorów dla poszczególnych pikseli. Wartości pikseli należy podmienić na aktualne indeksy z posortowanej tablicy kolorów. Po tej operacji ukrycie wiadomości odbywa się na takiej samej zasadzie jak w plikach JPG lub PNG, z tą różnicą, że zmianie ulegają nie poszczególne kolory składowych RGB, tylko indeksy kolorów. Po tej operacji następuje utworzenie nowego pliku GIF, na podstawie pliku wejściowego, poprzez podmianę danych na posortowaną tablicą indeksów oraz skompresowanych algorytmem LZW danych nowych indeksów pikseli. Wizualnie obraz wynikowy nie różni się od oryginału.

Różnica między kolorami poszczególnych pikseli w powyższym przykładzie jest dostrzegalna dopiero w dużym powiększeniu. Różnice te byłyby znacznie bardziej zauważalne, gdyby osadzenie wiadomości nastąpiło w kolejnych występujących po sobie pikselach. Ukrywana informacja została jednak rozłożona na cały obraz.

Obraz wejściowy (po lewej) i obraz z osadzoną wiadomością (opra- cowanie własne)

Obraz wejściowy (po lewej) i obraz z osadzoną wiadomością (opra-
cowanie własne)

Zaburzenia wprowadzone w kolorach pikseli, widoczne przy po- większeniu 800%. W odcieniach niebieskiego na obrazie po prawej stronie dostrzec można żółte piksele

Zaburzenia wprowadzone w kolorach pikseli, widoczne przy po-
większeniu 800%. W odcieniach niebieskiego na obrazie po prawej stronie dostrzec
można żółte piksele


1 Na podstawie https://www.w3.org/TR/WCAG20/relative-luminance.xml

Algorytm LSB

Algorytm najmniej znaczącego bitu (ang. Least Significant Bit) jest najprostszą i najczęściej stosowaną metodą steganograficzną dla obrazów. Przyjmijmy, że chcemy ukryć dowolne dane binarne (tekst, obraz lub inne dane przedstawione jako ciąg zer i jedynek), takie które zmieszczą się w naszym nośniku. Jako nośnik przyjmijmy obraz w formacie PNG w 24-bitowym trybie RGB. Format PNG stosuje bezstratny system kompresji, dzięki temu daje nam bezpośredni dostęp do informacji o poszczególnych pikselach i możemy stworzyć zmodyfikowany obraz bez obaw o “zgubienie” części danych podczas zapisu. Tryb 24-bitowy oznacza, że do dyspozycji mamy 3 kanały, nie używamy kanału Alpha.

Każde dane cyfrowe można przedstawić w postaci binarnej. Wprowadzone informacje przed ukryciem są przetwarzane na tablicę bajtów, a każdy bajt jest zapisywany za pomocą 8 bitów.

string jako ciąg bitów

Zmienna tekstowa String jako ciąg bitów.

Najmniej znaczącymi bitami są bity po prawej stronie w zapisie binarnym. Jeśli w każdej składowej zmienimy ostatni bit, to barwa piksela zmieni się na tyle nieznacznie, że oko ludzkie nie zarejestruje tej zmiany.
Kolor R: 11111110 G: 11111110 B: 11111110, czyli RGB (254, 254, 254), będzie tylko nieznacznie ciemniejszy niż rzeczywisty biały kolor.

Aplikacja przy odczytywaniu wiadomości powinna wiedzieć jak długo ma szukać ukrytych danych, dlatego na początku każdego pliku zostaje ukryta informacja o rozmiarze szyfrogramu. Informacje steganograficzne mają więc dwie części: wielkość komunikatu binarnego oraz samą wiadomość.

Poniżej został przestawiony przykład kodu w języku Java. Chociaż do operacji na bitach lepiej nadawałyby się języki niższego poziomu. Obraz jest wczytywany jako obiekt BufferedImage, co umożliwia pełną kontrolę nad pikselami obrazu. Metoda getRaster(), zwraca obiekt typu WritableRaster, w którym można modyfikować poszczególne piksele obrazu. Długość tablicy bajtów z danymi obrazu jest trzykrotnie większa niż obiektu BufferedImage. Klasa BufferedImage odwołuje się do pikseli obrazu, natomiast dalsza konwersja pliku rozkłada kolejne piksele na trzy kolory składowe RGB. Każdy zapisywany jest na 8 bitach, czyli 1 bajcie. W efekcie do zapisu danych o kolorze z jednego piksela potrzebujemy 3 bajtów. Tablica bajtów imageByte zawiera kolejno występujące po sobie składowe pikseli: RGBRGBRGB… Tablica msg zawiera treść ukrywanej wiadomości. W przypadku próby ukrycia tekstu, tablicę bajtów ze zwykłego typu String można uzyskać poprzez metodę getBytes() z opcjonalnym argumentem formatowania tekstu.

Przetworzenie nośnika i ukrywanej wiadomości na tablice bajtów.

public BufferedImage encryptImage(File file, byte [] text){

      BufferedImage image = bIP.getBufferedImage(file);
      WritableRaster raster = image.getRaster();
      DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();

      byte[] imageByte = buffer.getData();
      byte msg[] = text;
      byte len[] = BinaryConversion.toByteArray(msg.length);

      LSB.encodeText(imageByte, len, 0);
      LSB.encodeText(imageByte, msg, 32);

      return image;
}

Rozmiar jest przedstawiony jako typ Integer. Do zapisu takiej zmiennej w języku Java używane są 4 bajty, czyli 32 bity. Przyjęte zostało, że w każdym bajcie danych (jednej składowej koloru) zostanie zmieniony tylko jeden najmniej znaczący bit, aby zminimalizować zakłócenia w obrazie. Oznacza to, że ukrycie 1 bajta danych wymaga modyfikacji 8 bajtów obrazu. W efekcie do ukrycia liczby na 32 bitach, użyte zostaną 32 bajty, czyli pierwsze 32 elementy z tablicy reprezentującej obraz.

Pierwsze 32 bajty danych obrazu będą zawsze wykorzystane na osadzenie powyższej informacji. W kolejnych bajtach zawarta zostanie już konkretna wiadomość.

Zmiana obrazu w tablicę bitów

Zmiana obrazu w tablicę bitów

Zamiana liczby typu int na tablicę bajtów.

public class BinaryConversion {
     public static byte[] toByteArray(int length) {
           byte byte3 = (byte)((length & 0xFF000000) >>> 24);
           byte byte2 = (byte)((length & 0x00FF0000) >>> 16);
           byte byte1 = (byte)((length & 0x0000FF00) >>> 8 );
           byte byte0 = (byte)((length & 0x000000FF) );
           return(new byte[]{byte3,byte2,byte1,byte0});
     }
}

W powyższym kodzie liczba całkowita zostaje zamieniona na tablicę czterech bajtów, gdzie każdy bajt jest przedstawiony na 8 bitach. Wykorzystany został operator >>>, który w języku Java służy do przesuwania nieoznaczonych bitów w prawo.

Im więcej najmniej znaczących bitów w danym bajcie zostanie przeznaczonych do zmiany, tym dłuższą wiadomość można ukryć. Wprowadzenie znacznych modyfikacji do nośnika danych powoduje jednak pogorszenie jego jakości, a im bardziej obraz odbiega od oryginału, tym zwiększa się zagrożenie odkrycia wiadomości przez postronnego użytkownika.

Steganogram w najprostszym przypadku może być ukryty sekwencyjnie w kolejnych próbkach sygnału lub w wersji zmodyfikowanej tylko w określonych próbkach według wybranego klucza. Mogą to być przykładowo piksele o dwóch dominujących kolorach w obrazie lub rozmieszczenie w indeksach pikseli o określonej zależności, na przykład w co czwartym pikselu.

Jeżeli bitowo zapisana tajna informacja jest krótsza niż nośnik danych, to znaczy pozostają próbki niezmodyfikowane, dobrą praktyką jest uzupełnienie wiadomości, aby zwiększyć bezpieczeństwo danych. W przeciwnym razie ukryte dane mogłyby zostać łatwo wykryte za pomocą analizy statystycznej sygnału.

Przykładowo za pomocą trzech najmniej znaczących bitów każdej składowej 24-bitowego obrazu o rozdzielczości 800×600 punktów, można ukryć 1,44 mln bitów danych.

Ukrywanie bitów za pomocą podstawowego algorytmu LSB

Ukrywanie bitów za pomocą podstawowego algorytmu LSB

W celu utrudnienia wykrycia tajnej wiadomości w aplikacji zmiana nie powinna nastąpić w kolejno występujących po sobie wartościach tablicy obrazu, ale co
określoną (najlepiej losową) liczbę elementów. Dla ulatwienia w przykładowym kodzie przeskok (ozanaczony jako jump)jest zależny od wielkości obrazu opakowującego oraz długości ukrywanej wiadomości. Dodatkowo przyjęte zostało, że zmianie ulega tylko jeden najmniej znaczący bit w danym bajcie.

Ukrywanie wiadomości.

public class LSB {
      public static byte[] encodeText(byte[] image, byte[] addition, int offset) {
             if(addition.length + offset > image.length){
                  throw new IllegalArgumentException("File_not_long_enough!");
              }
       int jump =1;
       if(offset>0){
              jump = (image.length - offset)/(addition.length*8);
       }
       for (int i=0; i < addition.length; i++) {
             int byteVal = addition[i];
             for (int j=7; j >= 0; j--) {
                  int bitVal = (byteVal >>> j) & 1;
                  image[offset] = (byte)((image[offset]&0xFE) | bitVal);
                  offset+=jump;
             }
      }
      return image;
    }
}

Funkcja encodeText jako argumenty przyjmuje tablicę bajtów obrazu, tablicę bajtów osadzanych danych oraz przesunięcie. Wywoływana jest dwukrotnie. Pierwszy raz podczas ukrywania długości wiadomości. Wtedy przesunięcie zawsze wynosi 0, a liczba ukrywana jest w kolejnych 32 bajtach obrazu. Taki zabieg powoduje, że algorytm deszyfrujący wie w jaki sposób odczytać ukrytą wartość. Kolejne wywołanie ma na celu ukrycie treści właściwej tajnego przekazu. Przesunięcie wynosi 32 bajty, aby ominąć przestrzeń z ukrytą długością przekazu. Wiadomość właściwa nie musi już być ukrywana w kolejnych bajtach. Obliczany jest przeskok, nazwany w programie jako jump.

jump = (image.lengthoffset)/(addition.length ∗ 8);

Pozostała liczba bajtów obrazu, w których można ukryć dane, jest dzielona na ilość bitów tajnej informacji. Należy pamiętać, że przyjęta została zasada, że w jednym bajcie obrazu ukryty zostanie jeden bit wiadomości. Dzięki dodaniu przeskoku, wiadomość jest ukryta na obszarze całego pliku, a nie tylko jego początkowym fragmencie. Utrudni to wykrycie faktu zastosowania steganografii.

Zewnętrzna pętla for iteruje po każdym bajcie wiadomości przeznaczonej do ukrycia. Pętla wewnętrzna iteruje po kolejnych ukrywanych bitach wiadomości przy pomocy operatora >>>. W wyniku przesunięcia w prawo najbardziej znaczące bity ukrywanych danych stają się bitami najmniej znaczącymi i mogą być wstawione w miejsce najmłodszych bitów obrazu stanowiącego kontener. Zapis (byte)((image[offset] & 0xF E) | bitVal) przedstawia dany bajt obrazu jako reprezentację bitową a operacja alternatywy z zatajanym bitem pozwala na zmianę najmłodszego bitu na ukrywaną wartość.

Po lewej zdjęcie wejściowe, po prawej zdjęcie z ukrytym obrazem pizzy

Po lewej zdjęcie wejściowe, po prawej zdjęcie z ukrytym obrazem
pizzy

Grafika osadzona w powyższym zdjęciu

Grafika osadzona w powyższym zdjęciu

W powyższym przykładzie jako nośnik danych został użyty obraz PNG o bardzo dużym rozmiarze 5152×3888 pikseli. W tak dużym kontenerze bez problemu można ukryć inny plik – użyte zostało zdjęcie pizzy o wymiarach 1155×684 pikseli. Róźnica między oryginalnym zdjęciem a przetworzonym nie jest widoczna gołym okiem.

Największą wadą metody LSB jest to, że zazwyczaj łatwo wykryć ją przez programy służące do stegoanalizy. Każde przekształcenie nośnika danych powoduje też utratę zapisanych informacji.

Poniżej znajdują się porównanie dwóch wersji ukrytej grafiki z pizzą programem do wykonywania steganoanalizy – Steganabara. Analizie zostały poddane dwa pliki z ukrytą wiadomością. W pierwszym obraz został osadzony tradycyjnym algorytmem LSB, który umieszcza dane w kolejnych bajtach. W drugim użyty został algorytm zmodyfikowany z programu St3g0, używający przeskoku i rozmieszczenia danych w całym nośniku.

Na plikach został zastosowany filtr bitowych masek dla najmniej znaczących bitów każdego kanału koloru. Filtr analizuje warstwy bitowe, oddziela je i łączy w całość. Przy zastosowaniu tej metody dla obrazu z ukrytą wiadomością dla kolejnych składowych bez skoku w algorytmie, wyraźnie widać oddzieloną poziomą linię końca ukrytego obrazu. W przypadku z rozłożeniem ukrywanych bitów na cały plik wynik jest zbliżony do analizy obrazu bez ukrytej wiadomości

naliza filtrem masek bitowyc

analiza filtrem masek bitowych

Model kanału podprogowego w problemie więźnia

Poniższy wpis wyjaśnia pojęcie kanału podprogowego, który jest szczególną formą steganografii oraz obrazuje mechanizm wymiany informacji pomiędzy dwiema wtajemniczonymi stronami.

Kanał podprogowy to połączenie pozwalające na nawiązanie dodatkowej, ukrytej komunikacji między nadawcą i autoryzowanym odbiorcą niepozornie wyglądającej wiadomości.

W odróżnieniu od klasycznej steganografii kanały podprogowe nie tylko ukrywają istnienie tajnego przekazu w wiadomości, ale również go szyfrują. Wymiana tajnej korespondencji jest uzależniona od wspólnego klucza deszyfrującego między nadawcą a odbiorcą. Bezpieczeństwo metody jest więc uzależnione od poufności tego klucza, a nie od tajności algorytmu.

Same algorytmy i protokoły kryptograficzne również mogą zawierać kanały podprogowe, zwłaszcza jeśli wykorzystują losowe liczby. Kanały podprogowe stanowią podgrupę kanałów ukrytych [1]. Ukryty kanał umożliwia przesłanie informacji poprzez zastąpienie domyślnej wartości używanej do komunikacji innym parametrem.

Problem steganograficzny, jak i koncepcję kanału podprogowego najlepiej wyjaśnia abstrakcyjny model wymiany informacji pomiędzy dwoma więźniami stworzony przez Gustavusa Simmonsa [2].

Model kanału podprogowego

Wspólnicy Alice i Bob zostali schwytani i osadzeni w więzieniu w osobnych celach. Zamierzają opracować plan ucieczki. Nie mają jednak możliwości bezpośredniego kontaktu, mogą przekazywać sobie wiadomości jedynie przez strażnika – Wendy. Wartownik pozwala na komunikację pod warunkiem, że informacje zawarte w wiadomościach
są dla niego jawne. Strażnik ma możliwość nie tylko czytania korespondencji, ale również fabrykowania listów lub zmiany treści wiadomości przekazanych przez więźniów.
W takich warunkach aresztowani muszą znaleźć sposób na zaplanowanie ucieczki poprzez kanał podprogowy. Ponadto, ponieważ więźniowie przewidują oszustwo przez strażnika, chcą wymieniać tylko takie wiadomości, które będą mogli uwierzytelnić. Uwierzytelnienie zależy od wprowadzenia do wiadomości przez nadawcę nadmiarowej ustalonej wcześniej informacji. Aby zapobiec kopiowaniu tej dodatkowej treści i doklejeniu do sfabrykowanej wiadomości przez przeciwnika, strażnik musi zgodzić się na szyfrowanie wiadomości. W ten sposób wiadomość wraz z informacją uwierzytelniającą będą stanowiły blok tekstu zaszyfrowany jednym lub dwoma kluczami. Kanał uwierzytelnienia odgrywa kluczową rolę dla możliwości tajnej komunikacji, ponieważ będzie w nim stworzony kanał podprogowy. Innymi słowy, więźniowie podważają autentyczność komunikacji w zamian za możliwość przesłania tajnej wiadomości.

Sposób uwierzytelnienia wiadomości

Rozważmy najpierw samo uwierzytelnienie wiadomości bez kanału podprogowego.
Jeśli algorytm szyfrowania jest odpowiednio bezpieczny, to prawdopodobieństwo $P(A)$, że strażnik wybierze odpowiedni szyfr i podszyje się pod nadawcę wiadomości, jest związane z długością informacji uwierzytelniającej. Jeśli tajna informacja zapisana jest na $m$ bitach i $r$ bitów jest przeznaczonych na uwierzytelnienie, wówczas w zaszyfrowanej wiadomości zostaje przekazana łączna liczba bitów $(m + r)$ i $P(A) = 2^{-r}$.

Do szyfrowania wiadomości można użyć kryptografii symetrycznej lub asymetrycznej. W algorytmie symetrycznym do szyfrowania i deszyfrowania wiadomości używany jest ten sam klucz. Natomiast kryptografia asymetryczna (zwana również kryptografią klucza publicznego) wykorzystuje różne klucze, z czego jeden może być udostępniony publicznie bez naruszania bezpieczeństwa przesyłanej informacji. W opisywanym modelu używana jest druga opcja z kluczem publicznym i prywatnym. Wendy musi mieć dostęp do klucza, aby móc odszyfrować wiadomość i sprawdzić jej treść. Jeśli nadawca używa kryptoalgorytmu z jednym kluczem to udostępnia nadzorcy klucz szyfrujący/deszyfrujący po wymianie danych. W takim systemie kryptograficznym strażnik ryzykuje, że komunikacja między więźniami nastąpi przed poznaniem przez niego zawartości. Im dłuższa wiadomość, tym bardziej rośnie ryzyko skomunikowania się więźniów. Jeśli strażnik chciałby uniknąć tego ryzyka i mieć klucz wcześniej, wtedy nadawca wiadomości może zaprotestować, ponieważ pośrednik zyskałby możliwość podrobienia wiadomości.

Do rozwiązania tego problemu bardziej nadaje się kryptosystem z dwoma kluczami, ponieważ strażnik otrzyma klucz deszyfrujący przed każdą wymianą komunikatów, a zatem najpierw będzie mógł sprawdzić treść wiadomości przed przekazaniem jej dalej. Dopóki Wendy nie będzie znała klucza szyfrującego wiadomości Alice i Boba, nie ma możliwości polepszenia swoich szans w zgadywaniu szyfru uwierzytelniającego, a tym samym na oszukanie więźniów.

Wprowadzenie kanału podprogowego

Więźniowie przed aresztowaniem mogli ustalić między sobą, że zrezygnują częściowo z uwierzytelnienia w zamian za możliwość porozumiewania się w tajemnicy. W tym celu $s$ bitów z $r$ bitów informacji uwierzytelniającej, przeznaczają na przesłanie sekretnych informacji. Więźniowie mają teraz $(r – s)$ bity dostępne do uwierzytelnienia. Oznacza to wzrost prawdopodobienstwa, że strażnik jest w stanie oszukać więźniow do $P(A) = 2^{-(r – s)}$.

Rozważmy najkrótszy możliwy blok informacji, składający się z 3 bitów.
$h = m + (r – s)$, 1 bit jest przeznaczony na iadomość i 2 bity na informację uwierzytelniającą, z czego 1 bit został wydzielony na kanał podprogowy.

Sposób kodowania jest związany z wynikiem rzutu monetą. Jeśli w rzucie monetą wypadnie orzeł, to strażnik zgodzi się tylko na przesłanie parzystej wiadomości, gdzie parzystość oznacza parzystą sumę cyfr w binarnej reprezentacji wiadomości. Reszka natomiast symbolizuje wiadomość nieparzystą. Oznacza to, że więźniowie i strażnik godzą się na określoną z góry listę kluczy, przedstawioną w tabeli Tab. 1.

kostka binarna

Rys.1 Zbiór możliwych wiadomości przedstawiony na kostce bitowej w zależności od wyniku rzutu monetą. Tails oznacza zbiór dla reszki, natomiast heads dla orła.

Tab.1 Lista możliwych kluczy dla 1-bitowego kanału i 2-bitowego uwierzytelnienia
Orzeł Reszka
1 000 100
2 000 010
3 000 001
4 000 111
5 011 100
6 011 010
7 011 001
8 011 111
9 101 100
10 101 010
11 101 001
12 101 111
13 110 100
14 110 010
15 110 001
16 110 111

Strażnik nie wie jednak, który z 16 kluczy wybrali Alice i Bob przed zatrzymaniem.

Wendy może oszukać więźniów na dwa sposoby:

  • Przed rzutem monetą, czyli poprzez całkowite sfałszowanie treści wiadomości — wybiera losową wiadomość i podszywa się pod nadawcę. Jeśli wszystkie 16 kluczy są jednakowo prawdopodobne to szanse, na to, że wiadomość, którą wybrał strażnik będzie miała poprawny klucz wynoszą ${{4}\over{16}}={{1}\over{4}}$.
  • Po rzucie monetą — modyfikuje dostarczoną wiadomość, czyli zastępuje treść wiadomości przeciwnymi parzystościami. W takim wypadku jego wiadomość jest zawarta dokładnie w 4 kluczach, więc prawdopodobieństwo powodzenia wynosi również ${{1}\over{4}}$.

wiadomość podprogowa

Tab. 2 Lista możliwych kluczy dla 1-bitowego kanału, 1-bitowego kanału podprogowego i 1-bitowego uwierzytelnienia.
0 1 1 0
1 000 011 111 100
2 000 011 010 001
3 000 110 010 100
4 000 110 111 001
5 101 110 111 100
6 101 110 010 001
7 101 011 010 100
8 101 011 111 001

Rozważmy teraz jednobitowy kanał podprogowy, w którym więźniowie wybierają tajny klucz, nie z listy szesnastu, w którą wartownik wierzy, ale raczej spośród ośmiu kluczy pokazanych w tabeli Tab. 2. Każdy klucz na tej liście zawiera etykiety czterech narożników z listy Tab. 1 i każda wiadomość znajduje się dokładnie w czterech kluczach. Na przykład wiadomość 000 znajduje się w kluczach 1, 2, 3 i 4. Ważną rzeczą, na którą należy zwrócić uwagę na temat wpisów w tabeli Tab. 2, jest to, że środkowy bit w dowolnej kolumnie jest taki sam jak nagłówek podprogowej wiadomości kolumny oraz kolumny z parzystymi i nieparzystymi wiadomościami. Przekazanie podprogowego bitu wymaga od nadawcy wyboru tajnego klucza, który ma pożądany środkowy bit, wskazujący na parzystą lub nieparzystą wiadomość (w zależności od wyniku rzutu monetą).

Biorąc pod uwagę, że Bob zaakceptuje teraz każdą z czterech różnych wiadomości jako prawdziwą, dwie nieparzyste i dwie parzyste, prawdopodobieństwo udanego podszywania się przez strażnika ${{4}\over{8}} = {{1}\over{2}}$. Podobnie, jeśli strażnik czeka na wiadomość wysłaną przez Alice to wtedy prawdopodobieństwo pomyślnego zastąpienia wiadomości o przeciwnej parze w celu błędnego poinformowania Boba o wyniku rzutu monetą będzie również ${{1}\over{2}}$, ponieważ obserwowany komunikat pojawia się w czterech kluczach, z których dwa zawierają każdy z komunikatów o przeciwnej parzystości. Gdyby Wendy po każdej próbie oszustwa dostała informację zwrotną o powodzeniu podstępu, mógłaby zauważyć, że coś się nie zgadza.

W prawdziwym zastosowaniu prawdopodobieństwo sukcesu przy próbie oszustwa podczas uwierzytelnienia jest bardzo małe. Ponadto przedstawiony model nie zapewnia możliwości zmiany klucza przez więźniów w kolejnych komunikatach, aby pozbawić strażnika możliwości użycia wiadomości z poprzedniej wymiany.


Bibliografia

  1. G.J. Simmons, The Subliminal Channel and Digital Signatures. In: Beth T., Cot N., Ingemarsson I. (eds) Advances in Cryptology. Springer, Berlin, Heidelberg, 1985
  2. G.J. Simmons, The Prisoners’ Problem and the Subliminal Channel w Chaum D. (eds) Advances in Cryptology. Springer, Boston, MA, 1th edition, 1984

Rodzaje steganografii

Wybór nośnika ukrytych danych teoretycznie jest nieograniczony. Od prostych metod historycznych opartych na zjawiskach biologiczno-chemicznych przez steganografię językową po pliki cyfrowe i protokoły kryptograficzne. Niezależnie od rodzaju kanału komunikacji i sposobu ukrycia informacji, celem steganografii jest wprowadzenie dodatkowych danych w taki sposób, że informacja podstawowa pozostaje nienaruszona, a ponadto tajne dane mogą, choć nie muszą być zakodowane metodami kryptograficznymi. Wprowadzenie dodatkowego szyfrowania tajnej wiadomości zwiększa poziom jej bezpieczeństwa przy przesyłaniu.

Na system steganograficzny składają się takie elementy jak:

  • kontener, służący za medium do komunikacji;
  • algorytmy osadzania i wyodrębniania sekretnej informacji;
  • informacje konieczne do osadzenia i wyodrębnienia danych, pełniące funkcję klucza steganograficznego.

W pierwszej kolejności nośnik wiadomości, tajna informacja oraz klucz są przyjmowane w algorytmie osadzania jako dane wejściowe. Następnie na ich podstawie generowany jest obiekt z ukrytą treścią. Nowopowstały plik jest przekazywany do adresata ukrytej informacji. Odbiorca podaje otrzymany obiekt oraz znany klucz jako argumenty algorytmu wyodrębnienia. W ten sposób otrzymuje na wyjściu właściwą wiadomość przesłaną przez nadawcę [1].

Ze względu na sposób wprowadzenia steganogramu, czyli ukrytej wiadomości, możemy wyróżnić trzy kategorie metod steganograficznych [2].

  • Czysta steganografia (ang. Pure Steganography) — tajność komunikacji w tej metodzie opiera się na utrzymaniu w tajemnicy samego algorytmu steganograficznego. Sposób ukrywania informacji jest znany tylko nadawcy i odbiorcy wiadomości. Zaletą tego systemu jest fakt, że nie wymaga wcześniejszego ustalenia klucza do odszyfrowania wiadomości. Odbiór danych odbywa się na podstawie samej znajomości algorytmu tworzącego steganogram.
    Jednak stałość sposobu utajniania informacji wpływa niekorzystnie na jej bezpieczeństwo. Odkrycie algorytmu przez osobę niepowołaną kończy się zdemaskowaniem całej sekretnej komunikacji.
  • Steganografia z kluczem prywatnym (ang. Secret Key Steganography) — w tym sposobie występuje nawiązanie do szyfrowania symetrycznego, czyli zarówno do osadzenia, jak i odczytania steganogramu jest potrzebny jeden wspólny klucz. Największym problemem jest fakt, że klucz musi być ustalony wcześniej między komunikującymi się stronami i potrzebny jest bezpieczny sposób, aby go przekazać. Nikt poza nadawcą i odbiorcą wiadomości nie powinien mieć do niego dostępu.
  • Steganografia z kluczem publicznym (ang. Public Key Steganography) — wzorowana jest na kryptografii asymetrycznej, czyli wykorzystującej różne klucze do szyfrowania i deszyfrowania informacji. Jeden z użytych kluczy może być udostępniony publicznie bez naruszenia bezpieczeństwa przesyłanej informacji. Klucz publiczny wykorzystywany jest do wprowadzenia steganagramu, natomiast klucz prywatny służy do jego wyodrębnienia.

Połączenie technik steganograficznych z algorytmami kryptograficznymi może znacząco wpłynąć na poprawę ich bezpieczeństwa. Przed osadzeniem wiadomości w kontenerze danych, informacja może być zaszyfrowana dowolnym algorytmem i dopiero w takiej postaci zostać przesłana do odbiorcy. Techniki wykraczające poza czystą steganografię używają do przekazania wiadomości kanałów podprogowych. Kanały podprogowe zwykle wymagają wspólnego klucza między nadawcą a odbiorcą. Bezpieczeństwo metody zależy natomiast od tajności tego klucza, a nie od tajności algorytmu. Sposób konstruowania kanałów podprogowych może być publikowany bez zmniejszenia skuteczności tej techniki.


Bibliografia

  1. M.R. Ogiela Porównanie wybranych algorytmów steganografii cyfrowej. Pomiary, Automatyka, Kontrola : miesięcznik naukowo-techniczny. 60(12):1189–1195, December 2014
  2. S. Katzenbeisser and F.A.P. Petitcolas Information Hiding Techniques for Steganography and Digital Watermarking. Artech House Print on Demand, 1th edition, December 1999

Krótki zarys metod historycznych

Chociaż samo pojęcie steganografii pojawiło się dopiero w XV wieku, w książce niemieckiego mnicha Johannesa Trithemiusa [1], techniki ukrywania informacji były stosowane już w starożytności. Świadczą o tym zapisy w “Dziejach” Herodota [2], przedstawiające próby bezpiecznego przekazywania informacji na dalsze odległości, aby uniemożliwić przechwycenie wiadomości przez wroga.Jako przykład może służyć drewniana tabliczka z wyciętą wiadomością, którą ukryto pod warstwą wosku. Zewnętrzna warstwa służyła do zamieszczenia mało istotnego zapisu, aby nie wzbudzać podejrzeń. W ten sposób Sparta została ostrzeżona o planowanej perskiej inwazji. Innym przypadkiem opisanym przez Herodota jest tatuowanie ogolonej głowy niewolnika. Po odrośnięciu włosów posłaniec mógł bez problemu przemycić wiadomość.

Trithemius - Steganographia

Trithemius – Steganographia[4]

Kolejną stosowaną praktyką było pisanie listów sokiem z cytryny. Po wyschnięciu tekst był niewidoczny, aby go odczytać należało podgrzać papier.

Popularna była również steganografia językowa – znany jest przykład wiadomości ukrytej jako pierwsze litery poszczególnych wersów trzech sonetów ze zbioru “Amorosa visione” autorstwa Giovanniego Boccaccio.

Krata Cardana

Krata Cardana[5]

Bardziej zaawansowaną wersję językowej steganografii reprezentuje słynna krata Cardana, popularna w XVI wieku. Litery tajnej wiadomości zamiast regularnej struktury tworzyły losowy wzór. Odczytanie przekazu było możliwe poprzez umieszczenie nad tekstem specjalnej maski, tak zwanej kraty, która wskazywała poszczególne litery. Maska to wczesny przykład tajnego steganoklucza, który musiał być dzielony między komunikujące się strony. Prekursorem nowoczesnych metod steganograficznych był François Bacon. Bacon używał kursywy lub zwykłej czcionki do kodowania reprezentacji binarnych liter w swoich pracach.

Współcześniejszą i trudniejszą do wykrycia metodą były mikrokropki stosowane przez niemiecki wywiad podczas drugiej wojny światowej. Mikrokropka była punktem przypominającym zwykłą kropkę w druku, która zawierała zminiaturyzowany tekst lub obraz utworzony za pomocą aparatu fotograficznego i mikroskopu. Dzięki pomniejszeniu w skali 1:300 umożliwiała przesyłanie obrazów o wysokiej rozdzielczości, między innymi map wielkości kartki A4 w postaci zwykłej kropki w tekście. Udoskonalona technika laserowych mikrokropek jest stosowana do dziś przy znakowaniu żetonów w kasynach, aby trudniej było je podrobić [3].


Bibliografia

  1. J. Trithemius, Steganographia 1499, opubl. Frankfurt 1606
  2. Herodot, Dzieje (ks. VI: Erato)
  3. I. Cox, M. Miller J. Bloom, J. Fridrich, T. Kalker, Digital Watermarking and Steganography Morgan Kaufmann Publishers Inc. San Francisco, CA, USA 2008

Źródła grafik:

  1. https://en.wikipedia.org/wiki/Steganographia
  2. https://en.wikipedia.org/wiki/Cardan_grille

Wstęp — czym jest steganografia?

Ciągle postępująca informatyzacja społeczeństwa sprawiła, że coraz większa część naszego życia jest związana z globalnym przesyłem danych przez sieć internetową. Internet stał się istotnym medium komunikacyjnym, wykorzystywanym nie tylko na polu prywatnym, ale również w kontaktach służbowych lub oficjalnych sprawach urzędowych. W zaistniałej sytuacji głównym priorytetem stało się bezpieczeństwo udostępnianych treści. Konieczność ograniczenia grona odbiorców przesyłanych treści poprzez wprowadzenie elementu identyfikacji naszej tożsamości wpłynęła na powszechność stosowania kryptografii — dziedziny dbającej o szyfrowanie danych do postaci niezrozumiałej dla osób niepowołanych. Skuteczność ochrony udostępnianych informacji zależy więc od algorytmu szyfrowania.

Steganografia w odróżnieniu od kryptografii obejmuje obszar ukrywania danych w taki sposób, aby uniknąć podejrzeń, że jakiekolwiek informacje są ukryte. Głównym elementem zabezpieczenia tajnej wiadomości jest zachowanie w tajemnicy samego faktu jej istnienia.To sprawia, że steganografia nadaje się do zadań, w których nie jest wykorzystywane szyfrowanie, na przykład oznaczanie praw autorskich. Samo dodanie do pliku informacji o prawach autorskich może być łatwo usunięte. Dopiero osadzenie tych danych w treści pliku utrudnia ich identyfikację i usunięcie.

Samo hasło “steganografia” wywodzi się z języka greckiego i jest połączeniem słów steganos, czyli potajemny, ukryty oraz grapho – piszę, rysuję.

Steganografia to dziedzina nauki zajmująca się przeprowadzeniem komunikacji w taki sposób, aby fakt istnienia przekazywanej wiadomości był niemożliwy do wykrycia przez postronnego obserwatora [1].

Techniki steganograficzne były stosowane już w starożytności. W czasie wojen zdarzało się, że poufne informacje przekazywano na drewnianych tabliczkach, pokrytych następnie woskiem. Samo pojęcie steganografii nie jest więc niczym nowym, jednak ciągły rozwój technologii informatycznych pozwala na rozszerzenie sposobów jej zastosowania. Niezliczona ilość współistniejących ze sobą treści multimedialnych w globalnej sieci internetowej, daje ogromny potencjał ukrywania informacji w publicznie dostępnych plikach, nie wzbudzając przy tym podejrzeń. Wykorzystanie plików graficznych lub dźwiękowych jako nośniki danych do zamaskowania tajnych informacji jest jedną z najpopularniej stosowanych metod. Steganografia nie ogranicza się tylko do plików cyfrowych, ale daje również możliwość utworzenia ukrytych kanałów komunikacyjnych w protokołach sieciowych lub kanałów podprogowych w algorytmach stosowanych do podpisu cyfrowego. Różnorodność sposobów stosowania steganografii nie narzuca stałych reguł działania według schematów, ale pozwala na kreatywne modyfikowanie oraz udoskonalanie algorytmów pod kątem rozmiaru ukrywanych danych, trudności ich wykrycia lub trwałości po wprowadzeniu modyfikacji.

Wzrost znaczenie steganografii wpłynął na rozwój technik pokrewnych takich jak stosowanie znaków wodnych w plikach cyfrowych do oznaczenia praw autorskich. Znaki wodne (ang. Watermarking) są powszechnie spotykane na zdjęciach lub w plikach muzycznych. Mogą znajdować się w widocznym dla odbiorcy miejscu i jasno informować o autorze danego dzieła albo być ukryte w strukturze wewnętrznej pliku i pełnić funkcję niewidzialnego „odcisku palca”. Zamieszczenie w taki sposób numerów seryjnych lub innego zbioru cech odróżniających kopię od oryginału, pozwala wykryć osoby łamiące prawa autorskie.

Masowy przepływ cyfrowych informacji przez Internet dodatkowo wpływa na trudność w wychwyceniu i sklasyfikowaniu konkretnych działań jako świadome zatajanie danych. Dlatego steganografia bywa wykorzystywana przez agentów tajnych służb lub grupy przestępcze. Istnieje podejrzenie, że steganografia pomaga również w komunikacji terrorystów [2]. Uprawnione organizacje, czuwające nad bezpieczeństwem, mają duże powodzenie odszyfrowania przechwyconych danych kryptograficznych, jednak wychwycenie potajemnej komunikacji w gąszczu wymienianych informacji cyfrowych w sieci, wcale nie jest zadaniem trywialnym. W 2001 r. Uniwersytet w Michigan przeprowadził badanie na popularnym serwisie aukcyjnym eBay, gdzie sprawdzono ponad 2 mln plików graficznych. Ponad 17 tys. z nich uznano za podejrzane pod względem zastosowania steganografii.

Steganografia zapewnia poufność i integralność danych przy jednoczesnej ich dostępności. Pliki mogą znajdować się w kanale otwartym jak na przykład forum internetowe, ale jednocześnie dostęp do sekretnych informacji i możliwość ich modyfikacji mają tylko wybrani. Negatywnym aspektem stosowania takiej metody jest fakt, że informację może odczytać każdy, kto o niej wie i zna algorytm ukrywania danych. Problem ten można jednak rozwiązać, szyfrując wiadomość przed jej osadzeniem. Jeśli ktoś odnajdzie steganogram, nie będzie w stanie go odczytać. Z drugiej strony, jeśli ktoś chociażby podejrzewa użycie steganografii, to może łatwo zniszczyć ukrytą informację i nie dopuścić do jej odczytania przez odbiorcę.

Rozwój technologiczny znacząco wpłynął na rozbudowę dziedziny steganografii. Jest to nauka, która zdecydowanie ma przed sobą potencjał na dalsze poszerzanie zakresu działania wraz z wprowadzeniem nowych rozwiązań informatycznych.


Bibliografia

  1. C. Cachin, An information-theoretic model for steganography w Aucsmith D.(eds) Information Hiding. Springer, Berlin, Heidelberg, 2th edition, November 1998
  2. L. Grochowski, B. Hołyst, Steganografia a zagrożenia cyberterrorystyczne.