Browsing Category

steganography

Daj Się Poznać 2017 dotnetcore steganography

StegoCore – zakończona implementacja algorytmu Zhao&Koch

Jak obiecałem, tak robię. Po zakończeniu konkursu Daj Się Poznać nie ustają prace nad projektem StegoCore. Już na początku czerwca udało mi się dokończyć i poprawić implementację algorytmu Zhao&Koch, ale jestem leniem i zebrałem się dopiero teraz za napisanie posta. 😀

Co zrobiłem?

  • Wczytałem się dokładnie w opis algorytmu wstawiania i odczytywania znaku. Okazało się, że miałem w swojej implementacji błąd, który uniemożliwiał wstawienie, a co za tym idzie, odczytanie wiadomości.
  • Poprawiłem implementację oraz doświadczalnie dostosowałem parametry wykorzystywane podczas umieszczania znaku.
  • Dokonałem kilka poprawek w aplikacji webowej, tak aby możliwe było wykorzystanie algorytmu Zhao&Koch. W wolnej chwili wdrożę nową wersję aplikacji pod adres pawelskaruz.pl:8080

Co dalej?

  • Po pierwsze chciałbym poprawić aplikację webową, tak aby była używalna 😀 przyda się więcej komunikatów odnośnie umieszczania, odczytywania danych.
  • Do algorytmu Zhao&Koch potrzebny jest parametr d, który może pochodzić od użytkownika, więc chciałbym dodać taką możliwość. Będzie to oczywiście wymagać zmian zarówno w StegoCore, jak i w aplikacji webowej
  • Jeśli już zabiorę się za parametry wejściowe, to chciałbym dodać możliwość umieszczania bitów nie w kolejnych, a losowych miejscach zdjęcia. Myślę, że dobrym pomysłem będzie możliwość podania przez użytkownika hasła, które będzie seed’em do jakiegoś generatora pseudolosowego.
  • Następnym większym krokiem będzie implementacja mojego algorytmu opartego na Web Paper Codes.

I to na tyle dzisiaj. A już niedługo kolejna, 3 część z serii o bezpiecznej aplikacji ASP.NET Core 🙂

Daj Się Poznać 2017 dotnetcore imagesharp steganography

StegoCore – 10 tydzień. Koniec konkursu DSP i duże podsumowanie!

Minęło właśnie 10 tygodni prac nad projektem StegoCore w konkursie Daj Się Poznać. Jest to wiec ostatni tydzień i tym samym koniec konkursu. Ale zanim podsumuje cały projekt, czas na to co udało mi się zrobić w ostatnim tygodniu.

Co słychać?

  • Zaimplementowałem metodę odczytu ukrytej informacji w algorytmie Zhao&Koch
  • Napisałem testy sprawdzające możliwość odczytu ukrytej informacji – niestety wyniki nie są zadawalające; jest wiele przekłamań w odczytywanych bitach, co powoduje brak możliwości poprawnego odczytu danych. Wydaje mi się, że nie popełniłem żadnych błędów podczas implementacji, więc ciężko mi wywnioskować gdzie szukać błędu. Będę musiał dokładnie przeanalizować algorytm ukrywania i odczytu.
  • Zaktualizowałem aplikację webową dostępną pod adresem: http://pawelskaruz.pl:8080/

Co dalej?

  • Muszę przede wszystkich przetestować/przedebugować algorytm Zhao&Koch, aby dowiedzieć się dlaczego otrzymuje przekłamane bity podczas odczytywania.
  • Chciałbym poprawić aplikację webową StegoCoreWeb, wyłapać wyjątki z biblioteki StegoCore i przekazać odpowiednie komunikaty użytkownikowi

Podsumowanie konkursu

Przede wszystkim jestem zadowolony, że przez 10 tygodni udało mi się rozwijać projekt. Niestety wszystkie cele nie zostały osiągnięte. Na koniec konkursu chciałem zaimplementować 3 algorytmy i umieścić bibliotekę w menadżerze NuGet. Tak, jak wspominałem wcześniej, koniec konkursu nie oznacza końca prac nad projektem.

Gdy tylko uporam się z algorytmem Zhao&Koch, umieszczę bibliotekę StegoCore w NuGet. Dalej oczywiście będę rozwijał samą bibliotekę, jak i aplikację webową. Myślę tutaj o zaimplementowaniu własnego algorytmu ukrywania danych opartego na Wet Paper Codes.

Nie jestem za bardzo zadowolony z tylko 27 commitów, ale muszę wziąć pod uwagę fakt, iż mam tendencję to wrzucania wielu rzeczy na raz. Jest to jedna z kilku rzeczy, które muszę poprawić w swojej pracy. Commity nie powinny zawierać, aż tylu zmian w projekcie, a dotyczyć tylko jednej konkretnej zaimplementowanej/poprawionej rzeczy. Dzięki konkursowi nauczyłem się (a przynajmniej jestem świadomy, że muszę nad tym pracować 🙂 ) również innej, bardzo ważnej rzeczy – systematyczności. O wiele lepiej jest codziennie pracować nad projektem niż usiąść po kilku dniach przerwy i siedzieć wiele godzin przed komputerem.

Podczas prac nad StegoCore dosyć dobrze zapoznałem się z .NET Core. Jest to mój pierwszy projekt z użyciem tego frameworka, ale myślę że jak na pierwszy raz nie było tak źle. Do przeprowadzania operacji na zdjęciach użyłem biblioteki ImageSharp. Pomimo tego, że jest ona wciąż w fazie alpha, korzystało się z niej wygodnie i bez większych problemów.

W ramach Daj Się Poznać pisałem cotygodniowe podsumowania projektu, ale również inne posty związane z tematyką IT. TOP 5 najczęściej odwiedzanych to:

  1. Bezpieczna aplikacja ASP.NET Core (cz. I) – atak CSRF
  2. Kompresja JPEG oraz jej wykorzystanie w steganografii
  3. Alternatywa dla Visual Studio? Rider od JetBrains
  4. StegoCore – 3 tydzień, edycja zdjęć w .NET Core
  5. Klucz U2F jako metoda logowania do OS X

Reszta znajduje się pod adresem konkursowym. Serdecznie zachęcam do odwiedzania i czytania 🙂

Sukces!

Udało mi się wytrwać do samego końca konkursu Daj Się Poznać 2017! Yeah!! Sprostałem z wymogami i napisałem 20 postów konkursowych 🙂

Projekt będę dalej rozwijał, więc bardzo zachęcam do śledzenia bloga oraz dotnetomaniaka, na którego wrzucam swoje posty.

Na koniec chciałbym podziękować kilku osobom, które wspierały mnie podczas konkursu. Miewałem momenty zwątpienia i zniechęcenia, ale dzięki Wam nie poddałem się! Nie będę wymieniał z imienia i nazwiska, ale myślę, że te osoby będą wiedzieć, że chodzi o nie. Dzięki! 🙂

Daj Się Poznać 2017 dotnetcore steganography

StegoCore – podsumowanie po 9 tygodniach

Pora na podsumowanie po 9 tygodniach pracy nad projektem StegoCore.

Co słychać?

  • Zaktualizowałem wersję dotnetcore do 1.0.4 with SDK 1.0.1; wcześniej używana przeze mnie wersja była RC, wiec stwierdziłem, że warto spróbować przejść do nowszej. Nie spowodowało to żadnych dziwnych zachowań aplikacji, więc upgrade się udał.

    Krótka informacja jak wskazać aplikacji, aby korzystała z nowej wersji dotnet core.

    Po pierwsze należy zainstalować pożądaną wersję dotnet core np. podaną powyżej. Następnym i ostatnim krokiem jest zmienić numer wersji na nowo zainstalowany w pliku global.json, . W moim przypadku plik ten wygląda tak:

  • Dokonałem małego refactoringu w kilku miejscach biblioteki, a także aplikacji webowej: między innymi w kontrolerze bazowym
  • Napisałem testy sprawdzające poprawność metod kwantyzacji i obliczania dyskretnej transformaty kosinusowej; ku mojej uciesze przeszły pomyślnie 🙂
  • Skończyłem implementację metody ukrywania danych z algorytmu Zhao & Koch

Co dalej?

  • Z algorytmu Zhao & Koch została implementacja metody odczytu ukrytej informacji
  • Przetestowanie całego algorytmu Zhao & Koch
  • Niestety nie wystarczy mi już czasu, aby zająć się kolejnym algorytmem ukrywania danych. Dlatego do końca maja chciałbym popracować nad aplikacją webową; tak, aby była bardziej user friendly 🙂

Powoli zbliża się koniec konkursu „Daj się poznać”. Nie chcę kończyć jednak prac nad StegoCore i na pewno dalej będę rozwijał ten projekt. Wiem, że kilka osób go śledzi, więc daje mi to sporą motywację do działania! 🙂

 

Daj Się Poznać 2017 imagesharp steganography

StegoCore – powrót po przerwie, podsumowanie 8 tygodnia

Cześć wszystkim. Weekend majowy spowodował kolejną przerwę w pracach nad projektem. Nie jestem z tego dumny, ale nie ma co się zamartwiać, tylko brać do roboty. Na szczęście w maju nie ma chyba żadnych długich weekendów i przerw. Jestem więc dobrej myśli, jeśli chodzi o postępy w projekcie StegoCore.

Tuż przed majówką kończyłem powoli implementację algorytmu Zhao & Koch. Jednak tak strasznie namieszałem, że nawet ja nie byłem w stanie odnaleźć się w kodzie. Postanowiłem, więc zacząć od początku. Czas na podsumowanie tego, co udało mi się zrobić.

Co słychać?

W implementacji algorytmu Zhao & Koch pojawiły się:

  • Dyskretna transformata kosinusowa, metoda kwantyzacji oraz ich odwrotności
  • Zamiana bloku 8×8 pikseli na macierz luminancji
  • Wstawianie jednego bitu danych do bloku 8×8

Dodatkowo w bibliotece do obsługi plików graficznych ImageSharp zmieniła się struktura bibliotek. W związku z tym musiałem zaktualizować zależności w projekcie. Postanowiłem, że raz na dwa tygodnie będę sprawdzał te zależności, tak aby było to na bieżąco aktualne. Jest to niestety konieczne, ponieważ biblioteka ImageSharp jest wciąż w fazie alpha.

Pracowałem nad projektem na laptopie z Windowsem i byłem bardzo mile zaskoczony, gdy wszystko działało jak należy. Tak więc trzy platformy przetestowane (aplikacja demowa postawiona jest na serwerze z linuxem).

Przypominam, że wszystkie zmiany w projekcie na bieżąco wrzucam na githuba.

Co dalej?

  • Kontynuacja implementacji algorytmu Zhao & Koch
  • Przetestowanie metod liczenia transformaty i kwantyzacji
  • Aktualizacja dema aplikacji webowej

A przede wszystkim lepiej organizować czas i poświęcać go na projekt każdego dnia.

Daj Się Poznać 2017 jetbrains steganography

StegoCore – podsumowanie po 7 tygodniach

Kolejne, szybkie podsumowanie tego, co słychać w projekcie.

Co słychać?

  • Implementacja algorytmu Zhao & Koch trwa dłużej niż się spodziewałem. Aktualnie kończę algorytm umieszczania znaku w pliku graficznym. Myślę więc, że do końca tygodnia uporam się z całym tematem. Wtedy też implementacja pojawi się na githubie. A po przejściu testów, wypuszczę kolejną wersję demo aplikacji.
  • Na jakiś czas zmieniłem IDE na Rider. Sprawuje się zaskakująco dobrze, więc warto sprawdzić. Jeśli ktoś nie słyszał, to zapraszam na moją recenzję.
  • I to w sumie tyle 😀 a z takich mniej technicznych informacji – w trakcie ostatnich świat wielkanocnych nie dałem rady zająć się aplikacją, więc chcąc nie chcąc zrobiłem sobie tygodniową przerwę.

Co dalej?

Dokończenie implementacji algorytmu Zhao & Koch. To główny cel na najbliższy tydzień. Dalsze plany zależą od otrzymanych wyników. Jeśli będą one zadawalające (czyli gdy ukryty sekret w pliku graficznym będzie odporny na kompresję JPEG), zajmę się kolejnym algorytmem. Jeśli nie – optymalizacja algorytmu Zhao & Koch.

Daj Się Poznać 2017 steganography

Algorytm Zhao & Koch – ukrywanie danych odporne na kompresje JPEG

Pora na przedstawienie algorytmu ukrywania danych, który będzie odporny na kompresję JPEG. Zdecydowałem się na algorytm przedstawiony przez Jian Zhao i Eckhard Koch’a w 1996 roku. Jest on już trochę leciwy, ale posiada dobre wyniki odporności na kompresję.

Algorytm operuje w przestrzeni częstotliwościowej obrazu, więc nie zmieniamy poszczególnych pikseli. Do przejścia w przestrzeń częstotliwościową wykorzystywana jest transformata kosinusowa.

DCT

Dyskretna transformata kosinusowa (ang. discrete cosine transform) jest jedną z najpopularniejszych blokowych transformacji danych. DCT przekształca skończony ciąg N liczb f(0), f(1),…,f(N-1), w ciąg liczb rzeczywistych F(0), F(1),…,F(N-1) zgodnie z następującymi zależnościami:

DCT

Dyskretna transformata kosinusowa

Definiuję się również odwrotną transformatę kosinusową

Odwrotna transformata kosinusowa

Odwrotna transformata kosinusowa

Podczas kompresji danych używana jest dwuwymiarowa transformata kosinusowa zadana wzorem:

Dwuwymiarowa transformata kosinusowa

Dwuwymiarowa transformata kosinusowa

oraz przy dekompresja odwrotna:

Odwrotna dwuwymiarowa transformata kosinusowa

Odwrotna dwuwymiarowa transformata kosinusowa

Algorytm Zhao & Koch

W algorytmie zaproponowanym przez Jian Zhao i Eckhard Koch’a również zostały zastosowane elementy algorytmu kompresji JPEG. Autorzy zauważyli, że skwantyzowane współczynniki DCT mają umiarkowany poziom wariancji w środkowym zakresie częstotliwości. Niewielkie zmiany w tych współczynnikach, nie powinny być zauważalne dla oka ludzkiego. Dlatego do wstawienia znaku wodnego należy wybrać trzy współczynniki ze środkowego zakresu. Po spełnieniu odpowiednich zależności pomiędzy tymi elementami będzie możliwość umieszczenia wiadomości w obrazie.

Relacje pomiędzy trzema współczynnikami tworzą 9 kombinacji (wzorów), które zostały podzielone na trzy grupy: dwie do zakodowania „1” lub „0” oraz jednej nieprawidłowej. Jeśli potrzebne są zbyt duże modyfikacje, aby zakodować bit (w taki sposób zmienić współczynniki, by pasowały do poprawnego wzoru) wtedy blok jest nieprawidłowy. W takim przypadku trzy współczynniki należy zmodyfikować do niepoprawnego wzoru, aby blok został pominięty przy odczytywaniu wiadomości. Kryterium wyboru prawidłowego bloku jest parametr MD(ang. maximum difference), czyli maksymalna różnica pomiędzy dwoma wybranymi elementami.

Możliwe pozycje współczynników w bloku

Możliwe pozycje współczynników w bloku

W powyższym obrazie znajdują się możliwe pozycje współczynników transformaty kosinusowej dla bloku 8×8. Zostały one statystycznie wybrane przez autorów algorytmu. Tak jak to zostało wspomniane wcześniej, do zakodowania wiadomości należy użyć trzech współczynników. Możliwe kombinacje tych trzech elementów znajdują się w tabeli poniżej.

Nr wzoru (k1,l1) (k2,l2) (k3,l3)
1 2(0,2) 9(1,1) 10(1,2)
2 9(1,1) 2(0,2) 10(1,2)
3 3(0,3) 10(1,2) 11(1,3)
4 10(1,2) 3(0,3) 11(1,3)
5 9(1,1) 2(0,2) 10(1,2)
6 2(0,2) 9(1,1) 10(1,2)
7 9(1,1) 16(2,0) 2(0,2)
8 16(2,0) 9(1,1) 2(0,2)
9 2(0,2) 9(1,1) 16(2,0)
10 9(1,1) 2(0,2) 16(2,0)
11 10(1,2) 17(2,1) 3(0,3)
12 17(2,1) 10(1,2) 3(0,3)
13 10(1,2) 3(0,3) 17(2,1)
14 3(0,3) 10(1,2) 17(2,1)
15 9(1,1) 16(2,0) 17(2,1)
16 16(2,0) 9(1,1) 17(2,1)
17 10(1,2) 17(2,1) 18(2,2)
18 17(2,1) 10(1,2) 18(2,2)

Natomiast poniżej zostały przedstawione możliwe wzory trzech wybranych współczynników.

(k1,l1) (k2,l2) (k3,l3)
Wzór do zakodowanie „1” H M L
M H L
H H L
Wzór do zakodowanie „0” M L H
L M H
L L H
Nieprawidłowy wzór H L M
L H M
M M M

Do dostosowania widoczności i odporności znaku, służą dwa parametry: MD oraz d. Parametr MD został omówiony wyżej. Natomiast parametr d definiowany jest, jako moc wstawienia wiadomości do obrazu. W rzeczywistości, jest to odległość pomiędzy dwoma wybranymi współczynnikami transformaty. Jego domyślna wartość to 1. Im wyższy parametr d, tym wstawiony znak będzie odporniejszy na modyfikacje, jednak należy się liczyć z większą widocznością i podatnością na ataki.

W poniższych algorytmach przyjąłem następujące oznaczenie:

Yq(k, l)– skwantyzowane współczynniki transformaty bloku

Sprawdzenie możliwości zapisu

Sprawdzanie możliwości odczytu

Wstawianie znaku

Odczytywanie znaku

Do pracy!

Koniec tej teorii 🙂 czas zabierać się za implementację! Pisania kodu trochę będzie, ale to dobrze bo od ponad tygodnia nic w StegoCore nie dodawałem. Poznałem na czym opiera się kompresja JPEG i jak można ją wykorzystać do ukrycia danych. Algorytm Zhao & Koch nie wydaje się trudny i z samego pseudokodu można odnieść wrażenie że powinien działać. Wszystko jednak wyjdzie w testach, ale jestem dobrej myśli 🙂

Daj Się Poznać 2017 imagesharp steganography

Kompresja JPEG oraz jej wykorzystanie w steganografii

Kolejnym krokiem rozwoju biblioteki StegoCore jest implementacja algorytmu ukrywania danych, który będzie odporny na kompresję JPEG. Aby lepiej zrozumieć zasadę jego działania, należy zacząć od przedstawienia samego formatu JPEG. Jak wygląda kodowanie i dekodowanie pliku graficznego w kompresji JPEG? W jaki sposób zmienić plik jpeg, aby umieścić w nim sekretne dane? Odpowiedzi na te inne pytania w poniższym poście.

Co to jest JPEG i po co został wymyślony?

W celu ujednolicenia algorytmów kompresji obrazów monochromatycznych i kolorowych, powstał format JPEG. Jest on jednym z najczęściej stosowanych formatów grafiki rastrowej. Algorytm kompresji używany w formacie JPEG jest algorytmem stratnym. Oznacza to, że po skompresowaniu obrazu kosztem utraty niektórych informacji zmniejszamy jego rozmiar. Niemniej jednak, w zależności od wyboru stopnia kompresji, jest możliwość uzyskania jak najmniejszego pliku przy zadowalającej jakości.

Wymienione właściwości sprawiają, że format kompresji JPEG będzie dobrym w kontekście stosowania go jako nośnik steganograficzny. Sama kompresja niesie ze sobą sporo problemów, jednak popularność tego formatu zmniejsza ryzyko ewentualnego ataku. Jedną z pożądanych cech zaproponowanego algorytmu będzie odporność na kompresję JPEG. Oznacza to, że pomimo skompresowania obrazu nadal będzie możliwość odczytania ukrytej wiadomości. Aby dowiedzieć się od czego zależy to, czy daną wiadomość będzie można odczytać po kompresji, należy przyjrzeć się algorytmowi JPEG.

Algorytm kompresji

Algorytm kompresji JPEG jest algorytmem symetrycznym. Oznacza to, że operacje wykonywane podczas dekompresji, wykonują się w odwrotnej kolejności w stosunku do kompresji. W celu uproszczenia operacji zakłada się, że szerokość i wysokość obrazu są wielokrotnością 8. Jeśli warunek ten, nie jest spełniony, należy tego dokonać przed dodanie odpowiedniej ilości wierszy i kolumn.

Podczas kompresji obrazu możemy wyróżnić 6 następujących kroków.

Krok 1.

Pierwszym krokiem jest przejście do modelu luminancja-chrominancja. Zakładamy, iż wejściowy obraz zapisany w postaci modelu (R – ang. red – czerwony, G – ang. green – zielony, B – ang. blue – niebieski), a każda składowa jest liczbą całkowitą zawierającą się w przedziale . Przejście do modelu luminancja-chrominancja odbywa się w następujący sposób:

Krok ten jest pomijany, jeśli wejściowym obrazem jest obraz monochromatyczny.

Krok 2.

Po wykonaniu pierwszego kroku, otrzymujemy obraz zapisany w modelu luminancja-chrominancja. Następnie obraz jest dzielony na bloki 8×8 o rozmiarze pikseli. Dla każdej składowej YCbCr modelu tworzona jest macierz o podanych rozmiarach, aby działania na nich mogły być przeprowadzane niezależnie od siebie.

W celu uproszczenia obliczeń dokonywanych w następnych krokach, od każdego elementu macierzy odejmowana jest wartości równa połowie zakresu, czyli 128. W wyniku tego działania wszystkie elementy macierzy będą z zakresu [-128;127]. Przyjmijmy, iż po wykonaniu tego kroku każdy blok (macierz) można zapisać w następującej postaci:

Krok 3.

Dla każdego bloku obliczana jest dyskretna dwuwymiarowa transformata kosinusowa, zadana wzorem:

W wyniku otrzymamy macierz zawierającą wartości rzeczywiste. Zamiast samych wartości pikseli, mamy ich wartości średnie oraz częstotliwość zmian wewnątrz całego bloku. W przypadku dokładnych obliczeń nie tracimy żadnych danych, gdyż dyskretna transformata kosinusowa jest odwracalna.

Krok 4.

W wyniku obliczeń poprzednich kroków otrzymaliśmy macierz F, która jest transformatą kosinusową bloku danych f. W tym kroku wykonywana będzie operacja zwana kwantyzacją. Polega ona na usunięciu danych, które są mało lub wcale nie widoczne dla ludzkiego oka. Z postaci transformaty wynika, iż znajdują się one w prawej dolnej części macierzy. Proces kwantyzacji można podzielić na dwie części. W pierwszej, każdy element macierzy dzielony jest przez odpowiadającą mu stałą. Następnie otrzymane wartości zaokrąglane są do najbliższej liczby całkowitej. W wyniku tego zaokrąglenia, tracimy pewne dane. Jednak, jak zostało wspomniane, są to dane mało widoczne dla ludzkiego oka.

Stałe wykorzystywane w procesie kwantyzacji ułożone są w macierz zwaną macierzą kwantyzacji. Wartości tych stałych stanowią o tym w jakim stopniu wykonana zostanie kompresja obrazu – im większe one będą, tym więcej informacji zostanie utraconych. Po zaokrągleniu wiele elementów macierzy będzie równe zeru, co wpływa na rozmiar skompresowanego obrazu. Po procesie kodowania będą zajmować mniej miejsca.

Kwantyzację można przedstawić według następującej zależności

Macierz kwantyzacji decyduje o stopniu kompresji obrazu. Im wyższe są wartości jej elementów, tym wyższa kompresja. Jako przykład można podać macierz znajdującą się w dokumencie standaryzującym kompresję JPEG:

Współczynniki w macierzy zostały tak dobrane, aby uzyskana w wyniku kwantyzacji tablica zawierała jak największą liczbę zer. Zerowy element w jakimkolwiek miejscu w macierzy oznacza utratę pewnych informacji obrazu. Ważne jest, aby były one jak najmniej znaczące i mało widoczne dla oka ludzkiego. Takie informacje znajdują się w prawej, dolnej części macierzy . Natomiast w macierzy współczynniki znajdujące się w prawej, dolnej części są większe od pozostałych. W wyniku kwantyzacji otrzymamy dużą liczbę zer właśnie w tym obszarze macierzy.

Krok 5 i 6

Krok 5 to  przygotowanie danych do kodowania. W tym celu macierz transformowana jest na wektor według algorytmu zig-zag. Kolejność elementów w wektorze można przedstawić następująco:

Dzięki temu otrzymany ciąg będzie zawierał dużą liczbę zer, które dodatkowo będą znajdować się obok siebie. Pozwoli to na zastosowanie kodowania, które zmniejszy liczbę bitów potrzebną do zapisania skompresowanego obrazu.

Ostatnim krokiem jest kodowanie entropijne. Idea tego kodowania polega na zastąpieniu najczęściej występujących elementów krótszymi słowami kodowymi. Jest to zwykłe kodowanie Huffmana, dlatego nie będę go prezentował.

Podsumowując algorytm kodera można przedstawić jak poniżej:

Algorytm Dekompresji

Algorytm dekompresji JPEG jest odwróceniem algorytmu kompresji. Oznacza to, że operacje przeprowadzane są w odwrotnej kolejności. Wejściowy, skompresowany obraz dzielony jest na bloki, po czym każdy z nich przekształcany jest w dekoderze bitowym wykorzystującym tablice kodowe Huffmana. Po zastosowaniu algorytmu odwrotnego zig-zag, wektor zamieniany jest w tablice . Otrzymana tablica mnożona jest przez macierze kwantyzacji, w wyniku czego otrzymujemy przybliżoną tablice współczynników transformaty kosinusowej. Ostatnim krokiem jest obliczenie odwrotnej transformaty. Schemat algorytmu dekompresji można przedstawić następująco:

Pliki graficznego w formacie JPEG to dobry nośnik steganograficzny?

Tak jak wspomniałem na początku, pliki zapisane w formacie JPEG ze względu na swoje właściwości mogą być dobrymi nośnikami steganograficznymi. Aby wiadomość ukryta w obrazie była odporna na kompresję, musi zostać wstawiona w dziedzinie transformaty. Wadą tego rozwiązania będzie ilość bitów, którą można zakodować, gdyż zbyt duże modyfikacje spowodują widoczne zmiany w obrazie. Oczywiście zależy to również od obrazu, ponieważ nie we wszystkich miejscach w obrazie jest możliwość zapisania wiadomości. Nie zmienia to jednak faktu, iż ukrycie wiadomości w taki sposób, aby kompresja JPEG nie w usunęła jej z obrazu jest jednym z priorytetów algorytmu.

W którym miejscu można ukryć dane?

Z przeprowadzonych testów wiemy, że na pewno nie w najmniej znaczących bitach pikseli obrazu. Wtedy bowiem, podczas kompresji JPEG dane te są tracone (krok 4, czyli kwantyzacja). Możemy więcej spróbować tak zmodyfikować macierz 8×8 pikseli i w nich ukryć bity sekretu. Opis jak tego dokonać w kolejnym poście, w którym przedstawię pełny algorytm ukrywania danych.

Daj Się Poznać 2017 dotnetcore steganography

StegoCore – podsumowanie po pierwszym miesiącu

thumbs up

Właśnie minął pierwszy miesiąc pracy nad StegoCore. Czas na małe podsumowanie tego co udało się zrobić w tym czasie oraz jakie są plany na kolejny miesiąc.

Zrealizowane cele

Przede wszystkim udało się zaprezentować pierwszą wersję aplikacji webowej, która umożliwia ukrycie a następnie odczytanie pliku z danymi. Dosłownie przed chwilą poszedł commit z odpowiednimi zmianami. Sama aplikacja dostępna jest pod adresem:

 pawelskaruz.pl:8080

Ale może zacznijmy od początku.

  • Konfiguracja środowiska pracy oraz wybranie odpowiedniej wersji .NET Core
  • Wykorzystanie Yeomana do wygenerowania szablonów projektów biblioteki oraz aplikacji webowej
  • Wybranie ImageSharp jako bibliotekę do obsługi plików graficznych
  • Implementacja pierwszego algorytmu steganograficznego – LSB
  • Wykorzystanie algorytmu w aplikacji webowej

Aplikacja webowa wymaga jeszcze wielu poprawek (np. zabezpieczenie przed umieszczaniem zbyt dużych plików, nieudana próba odczytu sekretu). Niemniej jednak, jestem zadowolony że udało się zaimplementować pierwszy algorytm i wykorzystać go w aplikacji. Pierwszy miesiąc jak najbardziej na plus.

Co dalej?

  • Implementacja zabezpieczenia przed umieszczeniem zbyt dużych plików lub nieudaną próbą odczytu sekretnego pliku
  • Dodanie do aplikacji webowej kilku wyjaśnień, tak aby byłą bardziej „user friendly”
  • Implementacja kolejnych algorytmów ukrywania danych
  • Dodanie obsługi zapisywania wyjściowego pliku graficznego z ukrytymi danymi w różnych formatach (aktualnie tylko .bmp)
Daj Się Poznać 2017 security steganography

Steganografia? A co to jest? A komu to potrzebne?

Myślę, że część osób lub nawet większość może się zastanawiać czym jest w ogóle ta steganografia. Zacząłem projekt bez porządnego przedstawienia tematu. Nadrabiam więc zaległości.

Co to jest steganografia?

Steganografia jest nauką lub praktyką, z która prawdopodobnie spotykamy się na co dzień, zupełnie o tym nie wiedząc. Polega ona na ukrywaniu wiadomości, zdjęcia lub pliku w nośniku. Nośnikiem może być zdjęcie lub inna wiadomość. Istotny jest fakt, iż samo prowadzanie komunikacji(ukrywanie wiadomości) jest tajne. Głównym celem steganografii jest więc ukrycie w nośniku wiadomości, tak aby trzecia strona, czyli atakujący, nie była w stanie wykryć jej obecności. Samo słowo steganografia pochodzi z języka greckiego i oznacza „ukryte pisanie”.

W porównaniu do kryptografii, steganografia posiada pewną przewagę. Ukryta w dowolnym nośniku wiadomość nie zwraca na siebie uwagi. Natomiast w kryptografii, wiadomości są szyfrowane i mogą zostać wysłane publicznym kanałem. Tak więc, dużą zaletą stosowania steganografii jest to, iż sama wiadomość jest ukrywana w nośniku, oraz dodatkowo ukrywany jest sam fakt wysłania wiadomości. W poniższej tabeli prezentuje podstawowe właściwości steganografii i kryptografii.

Właściwość Steganografia Kryptografia
Ukrycie wiadomości Tak Nie
Użycie klucza Tak Tak
Ukrycie faktu komunikacji Tak Nie
Dodatkowy nośnik Tak Nie
Ilość przesyłanych informacji Większa od ilości wiadomości Porównywalna do wiadomości

W głównej mierze staganografia zajmuję się ukrywaniem informacji w plikach komputerowych. Wtedy możemy mówić o cyfrowej steganografii. Jak wspomniałem na początku, wiadomość może zostać ukryta w warstwie transportowej, czyli między innymi w plikach, zdjęciach, a także protokołach sieciowych. Najczęściej stosowane są pliki multimedialne. Głównym powodem ich wyboru jest duży rozmiar oraz fakt, iż zawierają dużo informacji nadmiarowych, których zmiana może nie być zauważona przez atakującego.

System steganograficzny

System steganograficzny można zdefiniować jako system składający z dwóch części: kodera i dekodera. Zadaniem kodera jest, przy użyciu klucza, umieszczenie w danym nośniku wiadomości. Klucz powinien być znany tylko nadawcy i odbiorcy. Znajomość klucza oznacza możliwość odczytania wiadomości. Schemat kodera systemu steganograficznego znajduje się na poniższym rysunku.

system steganograficzny

Koder systemu steganograficznego

 

Druga część systemu steganograficznego, czyli dekoder, służy do odczytania wiadomości. W zależności od wybranego algorytmu steganograficznego dekoder może składać się z różnych elementów. Jednak ogólny schemat powinien wyglądać jak na poniższym rysunku. Dekoder na podstawie klucza, odczytuje z nośnika wcześniej umieszczoną, sekretną wiadomość.

dekoder

Dekoder systemu steganograficznego

Chwila, chwila. A ukrywanie informacji to nie jest znakowanie wodne?

Możemy mieć wrażenie, że to o czym pisze to znakowanie wodne. Jest jednak spora różnica pomiędzy znakami wodnymi a steganografią.

Znak wodny to charakterystyczny obraz widzialny w świetle przechodzącym, powstający podczas formowania papieru. Jego najczęstszym zastosowaniem są zabezpieczenia banknotów oraz innych wartościowych dokumentów.

Cyfrowy znak wodny, jest to wiadomość zapisana w różnego rodzaju plikach np. obrazach, nagraniach dźwiękowych lub filmach wideo. Może być ona widoczna, tak jak w przypadku tradycyjnych znaków wodnych lub też niewidoczna. Wtedy do odczytania wcześniej zapisanej informacji, należy użyć programu wraz z zaimplementowanymi algorytmami.

Cyfrowy znak wodny, jest integralną częścią pliku, który został poddany oznakowaniu oraz nie potrzebuje żadnej dodatkowej pamięci. Oznacza to, że powstaje on kosztem pogorszenia jakości danych danego pliku. Znaki wodne, podobnie jak steganografia, są formą ukrywania pewnych informacji w nośnikach. Posiadają jednak wiele cech, które w znaczny sposób odróżniają je od wspomnianej steganografii. Cyfrowe znakowanie wodne można określić jako praktykę niedostrzegalnego umieszczania w nośniku pewnej informacji, traktującej o tym właśnie nośniku. Długość informacji jest zazwyczaj relatywnie mała. Natomiast fakt, iż dany nośnik zawiera znak wodny nie musi być ukrywany.

Porównując tą definicję do steganografii, możemy zauważyć podstawowe różnice. W steganografii ważniejsza jest niewykrywalność. W teorii, zmiana pewnych obszarów w nośniku, może być akceptowalna, ponieważ sam nośnik nie ma znaczącej wartości dla komunikujących się stron – ważna jest ukryta wiadomość. Oczywiście, zmiany nie mogą być zauważalne, ponieważ może to zwrócić uwagę atakującego. Druga znacząca różnica to pożądana długość wiadomości do ukrycia. W steganografii będzie ona dużo większa niż w aplikacjach do znakowania wodnego. W znakowaniu wodnym ukrywana jest informacja mająca związek z nośnikiem. Zazwyczaj jest to krótki podpis – od 8 do 128 bitów. Natomiast w steganografii, może to być tekst lub nawet rysunek.

Czyli podsumowując:

Właściwość Steganografia Znaki wodne
Ukrywana wiadomość Nie związana z nośnikiem Związana z nośnikiem
Długość wiadomości Duża Mała
Niewykrywalność Pożądana Nie ma znaczenia

A na co to komu?

Tak jak ze wszystkimi metodami związanymi z bezpieczną komunikacją, tak i steganografia może być wykorzystana w dobrych i złych celach. Jej główną ideą, tak jak to zostało wspomniane, jest umieszczenie wiadomości w wybranym nośniku. W połączeniu z pewnymi metodami kryptograficznymi, steganografia może posłużyć jako narzędzie do ochrony dokumentów, ograniczenia przeglądania danych czy ochrony przed kradzieżą. W tym ostatnim przypadku, w pliku zostaje umieszczony tzw. znak wodny, który może świadczyć o posiadanych do niego praw autorskich. W przypadku kradzieży, autor może przed sądem udowodnić swoje prawa do oznakowanego pliku.

Niestety, steganografia może zostać wykorzystana przez organizacje terrorystyczne lub szpiegów, do ukrywania faktu prowadzenia komunikacji. Po ataku 11 września 2001 roku na World Trade Center, mówiło się, że terroryści wymieniali rozkazy właśnie dzięki steganografii. Innym przykładem jest jej użycie do ukrywania pornografii, najczęściej dziecięcej, w niezwracających uwagi zdjęciach. Następnie takie zdjęcie, może zostać wysłane publicznym kanałem, np. w wiadomości e-mail lub jako post na forum. Steganografia może być również wykorzystywana przez hakerów do ukrycia kodu wykonawczego. Wtedy istnieje możliwość przeniesienia go nie zważając na zabezpieczenia, czy oprogramowanie antywirusowe np. na serwer ofiary. Następnie kod może zostać skopiowany do pamięci operacyjnej i wykonać niepożądane działania.

Daj Się Poznać 2017 security steganography

StegoCore – algorytm ukrywania danychs LSB

Czas na implementację pierwszego algorytmu steganograficznego. Zgodnie z zapowiedzią będzie nim algorytm LSB. Na początku kilka teoretycznych informacji na jego temat.

Algorytm LSB (pol. najmniej znaczący bit) jest jednym z najstarszych algorytmów wstawiania znaków wodnych. Polega na umieszczaniu kolejnych bitów wiadomości, w miejsce najmniej znaczących bitów nośnika. Ze względu na swoją prostotę, łatwo go zastosować w podpisywaniu obrazów i utworów audiowizualnych. Dla obrazów kolorowych, wiadomość można umieścić w najmniej znaczących bitach składowych RGB.

Metoda pozwala na umieszczenie dużej ilości informacji w obrazie, jednak jest bardzo mało odporna na operacje np. kompresję JPEG, przycinanie obrazu. Z jednej strony jest to wadą, ponieważ w wielu przypadkach można stracić zapisaną wiadomość. Jednak z drugiej strony, gdy zależy nam na tajnej komunikacji jest to zaletą. Prawie każda modyfikacja obrazu powoduje usunięcie sekretu.

Pseudokod algorytmu

Proces umieszczania wiadomości składa się z wybrania zbioru elementów, na których zostanie przeprowadzona operacja. Algorytm wstawiania i odczytywania wiadomości wygląda następująco:

Algorytm LSB – wstawianie znaku

Algorytm LSB – odczytywanie znaku

gdzie:
lsb(c) = najmniej znaczący bit elementu c

Głównym problemem, jest wybór elementów z obrazu, które zostaną poddane zamianie. W najprostszym rozwiązaniu mogą to być kolejne składowe RGB każdego piksela w obrazie rozpoczynając od pierwszego. Zazwyczaj będzie tak, że proces wstawiania wiadomości zakończy się dużo wcześniej, nie wykorzystując wszystkich dostępnych elementów. Może to spowodować wiele problemów związanych z bezpieczeństwem. Część obrazu z zakodowaną wiadomością, będzie posiadała inne właściwości statystyczne, w porównaniu z częścią, która nie uległa zmianie.

Aby temu zapobiec należy wybrać inny sposób wybierania elementów do zakodowania. Dobrym podejściem, jest użycie generatora pseudolosowego. Jeśli dwie osoby współdzielą klucz, mogą go użyć jako ziarno do generatora. W wyniku jego działania otrzymają sekwencję liczb , którą można użyć do wyboru elementów. Wtedy odległość pomiędzy dwoma zakodowanymi bitami będzie pseudolosowa. Odbiorca znając ziarno generatora może odtworzyć sekwencję oraz kolejne współrzędne określające wybór elementów z obrazu.

Co udało się zaimplementować?

Na tę chwilę w StegoCore zaimplementowałem algorytm bez zastosowania generatora pseudolosowego. Myślę, że w przeciągu tygodnia dodam również jego obsługę.

Zdecydowałem się również na umieszczenie bitów danych w dwóch (R i B) z trzech składowych piksela. Dzięki temu nie muszę się martwić o dopełnianie bitami gdyby długość sekretu była niepodzielna przez 3.

W edytowanym obrazie na samym początku będę umieszczał także długość ukrywanych danych. Jest to potrzebne podczas dekodowania, aby wiedzieć ile bitów odczytać. Czyli ostatecznie ukrywane dane (m) będą miały postać:

W związku z tym algorytm dekodowania zostanie lekko zmodyfikowany. Na początku odczytane zostaną 4 bajty, czyli 32 bity (długość danych zapisana jest w int32, który zajmuje właśnie 4 bajty). A następnie odczytane zostaną kolejne n bitów.

Zaimplementowany algorytm dostępny jest na github.

Co dalej?

Do realizacji pozostało kilka rzeczy, które przydadzą się również podczas implementacji innych algorytmów.

  • Sprawdzanie możliwości umieszczenia danych w obrazie – dane mogą być za duże
  • Generator pseudolosowy do wyznaczania miejsc osadzenia danych w pliku graficznym
  • Dodanie obsługi algorytmu w aplikacji webowej