Powrót do Kryptografia

steganografia w plikach dźwiękowych

Ukrywaliśmy już pliki, wiadomość i obrazki w różnych miejscach. Siłą rzeczy następnym miejscem, w którym ukryjemy nasze elementy, będą pliki dźwiękowe, do najprostszych, jeśli chodzi o strukturę, należy format WAVE. Jest on bardzo podobny do struktury formatu pliku BMP, do zapisu i odczytania danych używana jest konwersja bezstratna, dlatego możemy bez przeszkód, manipulować tymi danymi nie martwiąc się, że po ich zmianie dane ulegną uszkodzeniu lub będą błędnie odczytane. Plik WAVE składa się z trzech głównych elementów:

Nagłówek RIFF:

Podkategoria „fmt” opisuje format danych dźwiękowych:

Podkategoria „danych” zawiera rozmiar danych i rzeczywisty dźwięk:

Czasem występuje również podkategoria JUNK, która nadaje się do ukrycia tekstu w bardzo prosty sposób. W dalszej części pokaże algorytm, który będzie dodawał takie pola. Kategoria ta może występować zarówno po RIFF, jak i po „fmt „:

Można ją wygenerować sztucznie i wpisać w niej cokolwiek tylko chcemy, z zachowaniem pewnych zasad. Przykładowy program pozwalający na ukrycie pliku w bajtach nagłówka JUNK:

Taki program pobiera bajty pliku kontenera, oddziela dwanaście pierwszych bajtów i dodaje cztery bajty JUNK, wielkość bajtów pliku ukrytego, a następnie bajty ukrytego pliku i resztę bajtów kontenera. Pierwsza opcja pozwala na pobranie i zapis tych bajtów. Jeśli plik ukrywany nie jest duży, może zdezorientować analityka, który potraktuje te sekcje jako śmieci. Kolejną metodą dodania dodatkowych bajtów do kontenera jest przekształcenie nagłówka „fmt” przekształcając Subchunk1size, ExtraParamSize i ExtraParams:

Zasada działania jest taka sama jak przy dodawaniu nagłówka JUNK, w tym wypadku pobieramy bajty pliku i modyfikujemy obszary, aby następnie dodać dwa bajty wielkości tekstu/pliku i jego bajty. Wiemy już gdzie ukryć dane w strukturze pliku. Zajmijmy się samym dźwiękiem. Jak już wcześniej wspomniałem pliki w formacie WAVE, zawierają dane 8, 16, 24, lub 32 bitowe. Gdzie 8 bitowych plików WAVE już się nie używa. Zmiana dźwięku poprzez zerowanie LSB będzie najbardziej efektywna, gdy będziemy mieli do czynienia z plikami 32 bitowymi, ponieważ ich modyfikacje nie zmienią znacząco dźwięku, gdyż jego długość jest dosyć duża:

16 bit = 00 00 do  FF FF (0 do 65535)

24 bit = 00 00 00 do FF FF FF (0 do 16777215)

32 bity = 00 00 00 00 do FF FF FF FF (0 do 4294967295)

Zapożyczenie, nawet 2 bajtów w przypadku pliku 32 bitowego, nie pogorszy znacząco jego jakości. Przygotowałem aplikację, która prezentuje zmianę dźwięk po wyzerowaniu wskazanej ilości bajtów: program zerujący bity w pliku WAV

Aplikacja jest dosyć rozbudowana, ale jej działanie jest bardzo proste. Pobiera bajty pliku i segreguje je, umieszczając w odpowiednich listach, aby po modyfikacji można było połączyć je w całość i odtworzyć (wyświetlić histogram). Pliki, na których ja testowałem algorytmy::

16-bit.wav

24-bit.wav

32-bit.wav

Jeśli wyzerujemy ostatnie 8 bitów w 16 bitowym pliku WAVE, zmiana będzie niezauważalna (w dźwięku). Dopiero wyzerowanie więcej niż 10 bitów zmienia zauważalnie jakość dźwięku:

Procedura zerowania 8 bitów dla 16-bitowego pliku WAVe wygląda następująco:

Odpowiednio, dla pliku 16, 24, 32 bitowego( do pobrania na początku artykułu) zerowanie przebiega następująco:

ZerowanieOstatniegoBajtaW16bitowejPróbce  –> plik audio po zerowaniu ostatniego bajta: ZerowanieOstatniegoBajtaW16bitowejPróbce

ZerowanieOstatniegoBajtaW24bitowejPróbce  –> plik audio po zerowaniu ostatniego bajta: ZerowanieOstatniegoBajtaW24bitowejPróbce

ZerowanieOstatniegoBajtaW32bitowejPróbce  –> plik audio po zerowaniu ostatniego bajta: ZerowanieOstatniegoBajtaW32bitowejPróbce

Zachęcam was do przeprowadzenia takiego eksperymentu, przy użyciu algorytmu i sprawdzenia ich na własnych uszach. Ukrycie pliku w takim nośniku nie powinno sprawić wam problemu. Tak jak w przypadku plików graficznych w formacie bmp, zerujemy bity pliku dźwiękowego (kontener) i ukrywamy tam bity naszego pliku. Aby, nie zerować wszystkich bitów danych pliku WAV użyjemy czterech pierwszych bajtów danych do zapisania w nich wielkości pliku, warto również użyć formatu danych Uinteger(dlaczego, dowiesz się, rozwijając zakładkę projektu). Będzie to wyglądało następująco:

Plik WAVE 16-bitowy z ukrytym tekstem (ukryty plik)  :

Jeśli już rozbieraliście na części plik WAV, na pewno zauważyliście, że danych dźwiękowych jest bardzo dużo, więc z plik ukrywany może być znacząco mniejszy niż ilość danych dźwiękowych. Toteż ukrywanie wszystkich bajtów pliku tajnego na początku danych kontenera może spowodować słyszalny szum, dużo lepszą metodą jest podzielenie ilości dostępnych bajtów przez ilość bajtów pliku tajnego i zapisanie jego bajtów, w co piątym, szóstym czy siódmym elemencie:

Znając ilość ukrytych danych (pierwsze cztery bajty danych kontenera) bajty można rozłożyć w kontenerze tak jak na obrazku powyrzej.

plik ukryty w kontenerze: ukryty plik2

do odsłuchania, plik z ukrytymi danymi (16-bit wave z ukrytym plikiem „ukryty plik2”):

Przykładowy algorytm ukrywający bajty pliku w kontenerze WAV:

Jeśli wiemy jak dodawać bajty, ich wyciągnięcie nie stanowi problemu, z bajtów danych pobieramy informację na temat wielkości pliku i na tej podstawie wyodrębniamy bajty..

Plik wygenerowany, nie będzie miał rozszerzenia. Spowodowane jest to brakiem informacji (którą jeśli chcemy, możemy umieścić w kontenerze) o rodzaju pliku. Warto również połączyć możliwości JUNK i LSB.

Do przetestowania: Program_ukrywający_bajty_w_pliku_wav , Odzyskiwanie_ostatniego_bajta_z_pliku_WAV

(artykuł będzie rozwijany)

 

Permalink do tego artykułu: https://visualmonsters.cba.pl/kryptografia/steganografia-plikach-dzwiekowych/