Szyfry podstawieniowy to najprostszy i jednocześnie najłatwiejsze do zastosowania rodzaje szyfrów, znane już w starożytności. Ich historia sięga starożytnego Rzymu, w którym najsłynniejszy algorytm szyfrujący zastosował Juliusz Cezar. Opierał się on na zastąpieniu każdej litery, inną położoną o trzy miejsca dalej w alfabecie. Szyfry tego typu są łatwe do zastosowania, ale jednocześnie bardzo łatwe do złamania przy użyciu analizy statystycznej. Dopiero stosując je w informatyce, na pewnych poziomach możemy odnieść efekty skutecznego szyfrowania. Szyfr podstawieniowy nie jest specjalnie skomplikowany, aby go zastosować, obie strony muszą mieć wspólny alfabet i umówioną cyfrę. Szyfrowanie polega na za podstawieniu liter tekstu jawnego innych liter alfabetu przesuniętych o określoną wartość.
Zaszyfrować wiadomość jest stosunkowo prosto, trochę trudniej jest taką wiadomość odszyfrować. Szyfr ten ma bardzo dużo słabych stron. Oczywiście, aby utrudnić odszyfrowanie wiadomości można użyć kilku trików jak usunięcie spacji i indywidualny alfabet, ale nawet to tylko opóźni odszyfrowanie wiadomości. Im dłuższa jest zaszyfrowana wiadomość, tym łatwiej jest ją odszyfrować. Wystarczy spojrzeć na częstotliwość występowania określonych liter w języku polskim.
a | ą | b | c | ć | d | e |
---|---|---|---|---|---|---|
8,91% | 0,99% | 1,47% | 3,96% | 0,40% | 3,25% | 7,66% |
ę | f | g | h | i | j | k |
1,11% | 0,30% | 1,42% | 1,08% | 8,21% | 2,28% | 3,51% |
l | ł | m | n | ń | o | ó |
2,10% | 1,82% | 2,80% | 5,52% | 0,20% | 7,75% | 0,85% |
p | q | r | s | ś | t | u |
3,13% | 0,14% | 4,69% | 4,32% | 0,66% | 3,98% | 2,50% |
v | w | x | y | z | ź | ż |
0,04% | 4,65% | 0,02% | 3,76% | 5,64% | 0,06% | 0,83% |
Teraz do wiadomości należy dobrać litery do cyfr z częstotliwością ich występowania i poszukać znajomych krótkich słów kluczy, które pomogą nam w rozszyfrowaniu wiadomości i uzyskaniu klucza. Dużo trudniej jest odszyfrować szyfr przestawny z kluczem. Aby zastosować tego typ szyfr, obie strony muszą posiadać wspólny alfabet i hasło. Jedna strona, używając wspólnego alfabetu, najpierw zamienia hasło na wartości liczbowe odpowiadające literom w słowniku, na ich podstawie przestawia litery w wiadomości na podstawie powtarzającej się sekwencji przesunięć w haśle.
Komputer oferuje nam jednak dużo większe możliwości niż kartka papieru. Jeśli chcemy zaszyfrować wiadomość, przy użyciu szyfru przestawnego obie strony zawsze mają wspólny alfabet. Każdy znak generowany w komputerze ma swoją reprezentację w 7-bitowym kodzie przyporządkowującym liczby z zakresu 0−127 zwanym ASCII (czyt. aski; ang. American Standard Code for Information Interchange). Jest on jednakowy dla wszystkich komputerów niezależnie od kraju użytkowania i zawiera takie znaki specjalne jak spacja, tabulator itp. Jeśli spojrzymy na tabele kodów ASCII, znaki w niej podane są w następujący sposób:
Bin | Dec | Hex | Znak |
---|---|---|---|
01100001 | 97 | 61 | a |
Gdzie Bin oznacza system dwójkowy, Hex system szesnastkowy, Dec system dziesiętny. Aby Wyświetlić cyfrową reprezentację słowa „szyfr” skorzystamy z kodu poniżej, wyświetli on wartości numeryczne znaków w tabeli ASCII, hex i Bin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Module Module1 Dim wiadomosc As String = "szyfr" Dim ASCII_numery As String Dim Hex_n As String Dim Dec_n As String Dim Bin_n As String Sub Main() For i As Int32 = 0 To wiadomosc.Length - 1 Dim k As Integer = Asc(wiadomosc(i)) ' Convert to ASCII integer (Dec). ASCII_numery += k.ToString + "," Hex_n += Conversion.Hex(k) + "," ' Convert to HEX integer. Dim oReturn As New System.Text.StringBuilder 'Convert to Bin For Each Character As Byte In System.Text.ASCIIEncoding.ASCII.GetBytes(wiadomosc(i)) oReturn.Append(Convert.ToString(Character, 2).PadLeft(8, "0")) oReturn.Append(",") Next Bin_n += oReturn.ToString Next Console.WriteLine(ASCII_numery.ToString) '115,122,121,102,114 Console.WriteLine(Hex_n.ToString) '73,7A,79,66,72 Console.WriteLine(Bin_n.ToString) '01110011,01111010,01111001,01100110,01110010 Console.ReadLine() End Sub End Module |
ASCII ma taką zaletę, że każda ze stron dysponuje takim samym słownikiem. Stworzenie własnego alfabetu daje możliwość zwiększenia skuteczności szyfrowania, jeśli jednak druga strona nie dysponuje takim samym alfabetem, może nie odczytać wiadomości. Sposób, w jaki przestawimy nasze wartości, zależy tylko i wyłącznie od nas. Możemy przestawiać zarówno pojedyncze cyfry, jak i grupy.
Zastosowanie szyfru Cezara prezentuje poniższy kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Module Module1 Dim wiadomosc As String = "szyfr" Dim klucz As Integer = 3 Mod 127 Dim wiadomoscZaszyfrowana As String Dim wiadomoscOdszyfrowana As String Sub Main() For i As Int32 = 0 To wiadomosc.Length - 1 Dim k As Integer = Asc(wiadomosc(i)) wiadomoscZaszyfrowana += Chr((k + klucz) Mod 127) Next 'odszyfrowanie wiadomości For i As Int32 = 0 To wiadomoscZaszyfrowana.Length - 1 Dim k As Integer = Asc(wiadomoscZaszyfrowana(i)) If (k - klucz Mod 127) < 0 Then wiadomoscOdszyfrowana += Chr(127 + ((k - klucz) Mod 127)) Else wiadomoscOdszyfrowana += Chr(((k - klucz) Mod 127)) End If Next Console.WriteLine(wiadomosc.ToString) 'szyfr Console.WriteLine(wiadomoscZaszyfrowana.ToString) 'v}|iu Console.WriteLine(wiadomoscOdszyfrowana.ToString) 'szyfr Console.ReadLine() End Sub End Module |
Wykorzystując ASCII mamy ograniczoną ilość znaków w słowniku, jest ich 127 dlatego nasz klucz, musi mieć ograniczenie długości. Osiągamy to, wykorzystując operator Mod, zwraca on resztę z dzielenia jednej liczby przez drugą:
1 2 3 4 5 6 7 8 9 10 11 |
Sub Main() Console.WriteLine(56 Mod 127) 'Zwróci: 56 Console.WriteLine(156 Mod 127) 'Zwróci: 29 Console.WriteLine(200 Mod 127) 'Zwróci: 73 Console.WriteLine(500 Mod 127) 'Zwróci: 119 Console.ReadLine() End Sub |
I jest równoważne formule matematycznej: a Mod b = a – (b * Fix(a / b)) gdzie Fix oznacza zaokrąglenie w dół.
56 Mod 127 = 56-(127*Fix(56/127))=56-(127* Fix(0,4409448819)) = 56-(127*0)= 56
Zastosowanie klucza komplikuje szyfr. Aby zastosować klucz szyfrujący, musimy go najpierw przekształcić na kod ASCII i również zastosować Mod dla naszego klucza:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Module Module1 Dim wiadomosc As String = "Szyfr z kluczem szyfrujacym" Dim klucz As String = "cba" Dim wiadomoscZaszyfrowana As String Dim wiadomoscOdszyfrowana As String Sub Main() Dim mojklucz(klucz.Length - 1) As Integer For i As Int32 = 0 To klucz.Length - 1 Dim k As Integer = Asc(klucz(i)) mojklucz(i) = k Next ' mojklucz = {99,98,97} dla słowa "cba" For i As Int32 = 0 To wiadomosc.Length - 1 Dim k As Integer = Asc(wiadomosc(i)) wiadomoscZaszyfrowana += Chr((k + mojklucz(i Mod mojklucz.Length)) Mod 127) Next 'odszyfrowanie wiadomości For i As Int32 = 0 To wiadomoscZaszyfrowana.Length - 1 Dim k As Integer = Asc(wiadomoscZaszyfrowana(i)) If (k - mojklucz(i Mod mojklucz.Length) Mod 127) < 0 Then wiadomoscOdszyfrowana += Chr(127 + ((k - mojklucz(i Mod mojklucz.Length)) Mod 127)) Else wiadomoscOdszyfrowana += Chr(((k - mojklucz(i Mod mojklucz.Length)) Mod 127)) End If Next Console.WriteLine(wiadomosc.ToString) Console.WriteLine(wiadomoscZaszyfrowana.ToString) Console.WriteLine(wiadomoscOdszyfrowana.ToString) Console.ReadLine() End Sub End Module |
W efekcie nasze zdanie zostanie skutecznie zaszyfrowane:
„Szyfr z kluczem szyfrującym”= 7][JU^MPXE^HOV\]ITYMCG\O
Sami przyznacie, że ciężko by było odszyfrować taki tekst. Niestety wadą wykorzystania ASCII jest brak znaków narodowych, jeśli zechcemy użyć litery „ą” w zdaniu otrzymamy:
Szyfr z kluczem szyfrującym = 7][JU^MPXE^HOV\]ITYMG\O = (po rozszyfrowaniu) = Szyfr z kluczem szyfruj:cym
Nasza literka „ą” została zastąpiona znakiem „:” aby tego uniknąć, należy użyć systemu kodowania UTF-8, który zawiera w sobie ASCII i łącznie ma 1 112 064 znaków lub rozszerzenia ASCII- ISO 8859-16, które wykorzystując pierwszy nieprzypisany bit, dodaje 129 dodatkowych znaków wykorzystywanych w Południowo-wschodniuj Europie. UTF-8 wykorzystuje od 8 do 32 bitów, więc budowa znaku w tym kodzie jest bardziej skomplikowana, wykorzystanie ISO również czasem sprawia kłopoty, dlatego ominiemy te dekodery i wykorzystamy sobie wyłącznie ASCII. Można również wykorzystać Unicode lub inne odmiany UTF. Jeśli używamy języka vb.net, do szyfrowania wiadomości można zastosować wyłącznie Chr() i ChrW(), które zwiększają zakres ilości znaków: Chr() od 0 do 255 a ChrW() od -32768 do 65535.
Wykorzystanie konkretnego systemu kodowania:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Module Module1 Dim wiadomosc As String = "ąęć" Sub Main() For i As Int32 = 0 To wiadomosc.Length - 1 Dim bytes() As Byte = Encoding.GetEncoding("iso-8859-2").GetBytes(wiadomosc(i)) Dim str As String = "" For j As Integer = 0 To bytes.Length - 1 str += bytes(j).ToString + " " + System.Text.Encoding.GetEncoding("ISO-8859-2").GetString(bytes) Next Console.WriteLine(str) Next 'Zwróci: '177 dla znaku ą '234 dla znaku ę '230 dla znaku ć Console.ReadLine() End Sub End Module |
Listę systemów kodowania wykorzystywanych w vb.net można znaleźć pod adresem: https://msdn.microsoft.com…..
Wykorzystanie UTF-8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Dim wiadomosc As String = "cώጎ" Sub Main() For i As Int32 = 0 To wiadomosc.Length - 1 Dim bytes() As Byte = Encoding.UTF8.GetBytes(wiadomosc(i)) Dim str As String = "" For j As Integer = 0 To bytes.Length - 1 str += bytes(j).ToString + " " Next Console.WriteLine(str) Next 'Zwróci: '99 dla znaku "c" '207 142 dla znaku "ώ" '225 140 142 dla znaku "ጎ" Console.ReadLine() End Sub |
Zauważymy, że pierwsza litera kodowana jest jako jedna wartość ASCII, następna przez dwie a ostatnia przez trzy. Jeśli byśmy chcieli taką wiadomość zakodować, a następnie odkodować przysporzyłoby nam to trochę problemów, gdyż w zamian za trzy litery dostalibyśmy sześć liter. Oczywiście problem ten można usunąć, ale nie jest on tematem tego artykułu.
Więcej o systemach kodowania znaków, tabelach znaków można poczytać w Wikipedi: https://pl.wikipedia.org/wiki/ASCII, https://pl.wikipedia.org/wiki/ISO_8859
Kolejnym przykładem szyfru przestawnego jest szyfr wykorzystujący autoklucz. Znany również jako szyfr Vigenère’a z tą różnicą, że my nie wykorzystamy ustalonego alfabetu ani tablicy polialfabetycznej gdyż dysponujemy tablicą ASCII którą możemy dowolnie przekształcać. Polega on na tym, że pierwszą literę klucza ustalamy a kolejnymi klucza będą kolejne litery tekstu jawnego.
tekst jawny: Atakujemy rano
litera szyfrująca: N – ASCII(78)
ASCII tekstu jawnego: 65,116,97,107,117,106,101,109,121,32,114,97,110,111
A(65) + N(78) = 143 Mod 127 = 16
t(116) + A(65) =181 Mod 127 = 54
a(97) + t(116) = 213 Mod 127 = 86
k(107) + a(97) =204 Mod 127 = 77
ASCII tekstu zaszyfrowanego: 16,54,86,77,97,96,80,83,103,26,19,84,80,94
tekst zaszyfrowany: 6VMa`PSgTP^
Algorytm szyfrujący:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
Module Module1 Dim wiadomosc As String = "Atakujemy rano" Dim klucz As Char = "N" Dim wiadomoscZaszyfrowana As String Dim wiadomoscZaszyfrowanaASC As String Dim wiadomoscOdszyfrowana As String Sub Main() Dim k As Integer = Asc(klucz) For i As Int32 = 0 To wiadomosc.Length - 1 Dim y As Integer = Asc(wiadomosc(i)) wiadomoscZaszyfrowana += Chr((y + k) Mod 127) wiadomoscZaszyfrowanaASC += ((y + k) Mod 127).ToString + "," k = y Next 'odszyfrowanie wiadomości Dim z As Integer = Asc(klucz) For i As Int32 = 0 To wiadomoscZaszyfrowana.Length - 1 Dim y As Integer = Asc(wiadomoscZaszyfrowana(i)) If ((y - z) Mod 127) < 0 Then wiadomoscOdszyfrowana += Chr(127 + ((y - z) Mod 127)) Else wiadomoscOdszyfrowana += Chr(((y - z) Mod 127)) End If z = (127 + ((y - z) Mod 127)) Next Console.WriteLine(wiadomoscZaszyfrowana.ToString) Console.WriteLine() Console.WriteLine(wiadomoscZaszyfrowanaASC.ToString) Console.WriteLine() Console.WriteLine(wiadomoscOdszyfrowana.ToString) Console.ReadLine() End Sub End Module |
Jeśli znamy algorytm szyfrujący, nie będzie dla komputera problemem sprawdzenie wszystkich 127 możliwości wyboru liter i odszukania słów kluczy.
Musimy wiedzieć, że po zaszyfrowaniu tekstu i wyświetleniu go na ekranie, często jest tak, że tekst z użytym kodowaniem ASCII może natrafić na taki znak, który po zaznaczeniu, skopiowaniu i zapisaniu może zostać zniekształcony, dlatego po zaszyfrowaniu należy utworzyć plik z zaszyfrowaną wiadomością, pozwoli to na zachowanie oryginalnego kodu bez zniekształceń:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
Module Module1 Dim wiadomoscZaszyfrowana As String Dim wiadomoscOdszyfrowana As String Sub Main() 'zwiększa ilość możliwych do wpisania liter w konsoli Dim bufSize As Integer = 1024 Dim inStream As IO.Stream = Console.OpenStandardInput(bufSize) Console.SetIn(New IO.StreamReader(inStream, Console.InputEncoding, False, bufSize)) '''''''''''''''''''' Console.Write("Wprowadź tekst do zaszyfrowania: ") Dim wiadomosc As String = Console.ReadLine() Console.Write("Wprowadź klucz szyfrujący: ") Dim klucz As String = Console.ReadLine() Dim mojklucz(klucz.Length - 1) As Integer For i As Int32 = 0 To klucz.Length - 1 Dim k As Integer = Asc(klucz(i)) mojklucz(i) = k Next For i As Int32 = 0 To wiadomosc.Length - 1 Dim k As Integer = Asc(wiadomosc(i)) wiadomoscZaszyfrowana += Chr((k + mojklucz(i Mod mojklucz.Length)) Mod 127) Next 'lokalizacja zapisu zapisanego szyfru Dim LokalizacjaZapisu As String = "C:\Users\piotr\Desktop\" Console.Write("Wprowadź nazwę pliku zaszyfrowanego: ") Dim NazwaPliku As String = Console.ReadLine() Dim sw As New IO.StreamWriter(LokalizacjaZapisu + NazwaPliku, False) sw.Write(wiadomoscZaszyfrowana) sw.Close() Console.WriteLine(wiadomosc.ToString) Console.WriteLine(wiadomoscZaszyfrowana.ToString) Console.ReadLine() End Sub End Module |
Taki plik wczytamy za pośrednictwem kodu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
Module Module1 Dim wiadomoscZaszyfrowana As String Dim wiadomoscOdszyfrowana As String Sub Main() Dim SciezkaDoPliku As String = "C:\Users\piotr\Desktop\szyfr" Dim rodzajkodu As New IO.StreamReader(SciezkaDoPliku) wiadomoscZaszyfrowana = rodzajkodu.ReadToEnd() rodzajkodu.Close() Console.WriteLine("wiadomość została załadowana z pliku: " + SciezkaDoPliku) Console.Write("Podaj klucz szyfrujący: ") Dim klucz As String = Console.ReadLine() Dim mojklucz(klucz.Length - 1) As Integer For i As Int32 = 0 To klucz.Length - 1 Dim k As Integer = Asc(klucz(i)) mojklucz(i) = k Next 'odszyfrowanie wiadomości For i As Int32 = 0 To wiadomoscZaszyfrowana.Length - 1 Dim k As Integer = Asc(wiadomoscZaszyfrowana(i)) If (k - mojklucz(i Mod mojklucz.Length) Mod 127) < 0 Then wiadomoscOdszyfrowana += Chr(127 + ((k - mojklucz(i Mod mojklucz.Length)) Mod 127)) Else wiadomoscOdszyfrowana += Chr(((k - mojklucz(i Mod mojklucz.Length)) Mod 127)) End If Next Console.WriteLine(wiadomoscZaszyfrowana.ToString) Console.WriteLine(wiadomoscOdszyfrowana.ToString) Console.ReadLine() End Sub End Module |
Efektem jest utworzenie pliku w podanej lokalizacji o ustalonej nazwie:
Drugie narzędzie daje nam możliwość odszyfrowania wiadomości:
Dzięki tym narzędziom możemy utworzyć proste oprogramowanie, dzięki któremu będziemy mogli z ustalonym kluczem tworzyć i odczytywać zaszyfrowane wiadomości powyższymi metodami. Szyfrować za pomocą tych prostych metod można nie tylko tekst ale również piksele. Piksel jest to najmniejszy jednolity (przedstawiający konkretny kolor) element obrazu wyświetlanego na ekranie. Jeśli użyjesz Painta do stworzenia obrazka zauważysz, że każdy kwadracik składa się z trzech kolorów, paleta ta nazywana jest RBG (red, blue, green) i przyjmują wartości od 0-255. Kolor czarny będzie miał reprezentacje RBG(0,0,0), biały(255,255,255), czerwony(255,0,0) itd. Istnieje możliwość dodania kanału Alfa ale nie będzie on omawiany w naszym eksperymencie. Aby edytować piksele obrazu, należy go najpierw pobrać do bufora, edytować jego piksele i nadpisać. Po przeczytaniu powyższej części każdy artykułu każdy z was powinien powiedzieć pomyśleć, że to nic trudnego.Wystarczy przestawić wartości piksela o wartość klucza w prawo lub w lewo i kiedy mamy piksel RGB(243,254,53) przesunięcie w prawo o 3 (tak jak w przypadku szyfru cezara) załatwi sprawę:
RGB(243,254,53)—-> 3 —–>RGB(246,2,56), czy takie podstawienie ma sens? Czy przestawienie tych wartości o 30 lub o 167 ma sens? zobaczmy:
Kod użyty do przestawienia wartości pikseli :
Jak widzicie nie dało to zadowalających efektów, nadal widać, że to kot. Szyfr z kluczem daje lepsze efekty ale jest w dużym stopniu zależny od jego długości :
Kod użyty do przestawienia wartości pikseli :
Problem jeśli chodzi o klucz polega na tym, że litery użyte w kluczu zarówno krótkim jak i długim są stosunkowo blisko siebie a pikseli jest często bardzo dużo. Zmiana barwy piksela o małą wartość 3, 2 lub 4 w górę czy w dół jest dla ludzkiego oka dosłownie niezauważalna. Dlatego nasz kod należy zmienić tak aby zmiany wartości były bardzo duże.
Wplecenie do pętli indeksu rosnącego:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Dim index As Integer = 0 For y = 0 To ymax For x = 0 To xmax With bmp.GetPixel(x, y) R = (.R + (mojklucz(index Mod mojklucz.Length) + index)) Mod 256 index += 1 G = (.G + (mojklucz(index Mod mojklucz.Length) + index)) Mod 256 index += 1 B = (.B + (mojklucz(index Mod mojklucz.Length)) + index) Mod 256 index += 1 End With bmp.SetPixel(x, y, Color.FromArgb(R, G, B)) Next x Next y |
Przemnożenie wartości ASCII klucza przez 10:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
For y = 0 To ymax For x = 0 To xmax With bmp.GetPixel(x, y) R = (.R + (mojklucz(index Mod mojklucz.Length) * 10)) Mod 256 index += 1 G = (.G + (mojklucz(index Mod mojklucz.Length) * 10)) Mod 256 index += 1 B = (.B + (mojklucz(index Mod mojklucz.Length)) * 10) Mod 256 index += 1 End With bmp.SetPixel(x, y, Color.FromArgb(R, G, B)) Next x Next y |
Algorytm pobierający znaki(tekst) z pliku:
Przykładowy kod deszyfrujący:
Efekt przy użyciu klucza: kryptografiajestEkstra
Niestety ale gdy nasz obrazek jest mało szczegółowy:
Efekt może być niezadowalający, mimo iż powyższy obrazek jest zaszyfrowany, bardziej wygląda to jak znak wodny który mimo wszystko da się odczytać.
Jak więc używając szyfru podstawieniowego i przestawić piksele tak aby kotek był niewidoczny całkowicie. Aby użyć naszego szyfru na tym etapie, można zastosować stworzenie klucza automatycznie i zapisanie go oddzielnie w pliku, klucz taki może być obrazkiem lub listą przesunięć:
Lista przesunięć:
Przykład takiego algorytmu:
Algorytm deszyfrujący:
dla klucza w formacie graficznym algorytm wygląda podobnie:
Algorytm szyfrujący:
Algorytm deszyfrujący:
Takie przestawianie pikseli jest bardzo efektywne, niestety klucz jest dość długi i duży. Również konieczność posiadania klucza przez obie strony powoduje problemy, im bardziej klucz jest rozpowszechniony tym większa jest szansa na jego zdobycie przez potencjalnego złodzieja, ponieważ bez klucza, druga strona nie jest w stanie, nawet przy użyciu najnowszej technologi odczytać obrazu. Wszystko w komputerze to liczby, obrazy, filmy, muzyka a przynajmniej z tego się składają. Jeśli tak można by było również przestawiać cyfry w filmie, muzyce, grafice itp. Każdy plik na komputerze składa się z 1 i 0 te łączą się w bajty. Jeden bajt składa się z 8 bitów. Bity można przedstawić w formie binarnej, może przechowywać wartość od 0 – 11111111 dla notacji dziesiętnej będzie to 0-255 a szesnastkowej 0-ff. Tak więc jeśli pobierzemy wszystkie bajty danego pliku i przestawimy je o 3 w prawo nasz plik będzie zaszyfrowany. Stworzyłem sobie, przy użyciu Painta plik graficzny bmp który składa się z czterech białych pikseli. Użyłem programu HxD do podejrzenia wnętrza tego pliku:
Plik składa się z nagłówka i danych, ale w tym artykule nie będziemy się zajmować tym z czego on się składa bo wszyscy widzą z czego, składa się z liczb (tutaj w systemie szesnastkowej). Wystarczy je przy użyciu odpowiedniego algorytmu pobrać, jeden po drugim i przestawić. Tak zmieniony plik jest nie do otworzenia, gdyż przed danymi znajduje się ważne informacje o pliku, jego strukturze, wymiarach, palecie barw, rodzaju kompresji itp, które są wymagane do otworzenia pliku.
Tak zmieniony plik jest nie do odczytania, nawet do otworzenia. Prosty algorytm szyfrujący bajty metodą podstawieniową:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
Imports System.Windows.Forms Module Module1 Dim lokalizacjaPliku As String Dim klucz As Integer = 3 Mod 256 Sub Main() Dim open_dialog As New OpenFileDialog() open_dialog.InitialDirectory = "c:\" open_dialog.Filter = "All Files|*.*" If open_dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then lokalizacjaPliku = open_dialog.FileName Dim File_bytes As Byte() = IO.File.ReadAllBytes(lokalizacjaPliku) Dim wartoscLiczbowaBajta As Integer = 0 For i As Integer = 0 To File_bytes.Count - 1 wartoscLiczbowaBajta = Convert.ToInt32(File_bytes(i)) wartoscLiczbowaBajta += klucz File_bytes(i) = Convert.ToByte((wartoscLiczbowaBajta Mod 256)) Next IO.File.WriteAllBytes("C:\Users\piotr\Desktop\" + IO.Path.GetFileNameWithoutExtension(lokalizacjaPliku).ToString, File_bytes) Console.WriteLine("Bajty pliku zostały przestawione.") Console.ReadLine() End If End Sub End Module |
Algorytm deszyfrujący:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Imports System.Windows.Forms Module Module1 Dim lokalizacjaPliku As String Sub Main() Dim open_dialog As New OpenFileDialog() open_dialog.InitialDirectory = "c:\" open_dialog.Filter = "All Files|*.*" If open_dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then lokalizacjaPliku = open_dialog.FileName Dim File_bytes As Byte() = IO.File.ReadAllBytes(lokalizacjaPliku) Dim klucz As Integer Console.WriteLine("Podaj wartość klucza:") Do Dim wejscie As String = Console.ReadLine() If IsNumeric(wejscie) Then klucz = wejscie Mod 256 Exit Do Else Console.WriteLine("Klucz musi być liczbą.") End If Loop Dim wartoscLiczbowaBajta As Integer = 0 For i As Integer = 0 To File_bytes.Count - 1 wartoscLiczbowaBajta = Convert.ToInt32(File_bytes(i)) If wartoscLiczbowaBajta - klucz < 0 Then wartoscLiczbowaBajta = 256 + (wartoscLiczbowaBajta - klucz) File_bytes(i) = Convert.ToByte(wartoscLiczbowaBajta) Else wartoscLiczbowaBajta -= klucz File_bytes(i) = Convert.ToByte((wartoscLiczbowaBajta)) End If Next IO.File.WriteAllBytes("C:\Users\piotr\Desktop\" + IO.Path.GetFileNameWithoutExtension(lokalizacjaPliku).ToString + " odszyfrowany kluczem " + klucz.tostring, File_bytes) Console.WriteLine("Bajty pliku zostały przestawione.") Console.ReadLine() End If End Sub End Module |
Tak samo jak wcześniej, nic nie szkodzi na przeszkodzie użyć klucza lub autoklucza, trzeba pamiętać tylko, że bajty przyjmują wartości od 0-255 i uda wam się to bez problemu.