3EF/AA-DI L6 zespół 1 22.01.2014 |
Rozproszone systemy sterowania Projekt realizujący szyfrowanie i deszyfrowanie za pomocą User Function Blocks - dokumentacja |
Adam Kubicki Dawid Zięba Jakub Zimoń |
Cel projektu
Celem naszego projektu była realizacja algorytmu szyfrującego, a następnie deszyfrującego za pomocą UFB (User Function Block). Stworzone w projekcie UFB pozwalają na zaszyfrowanie i odszyfrowanie zmiennej znakowej typu STR256 za pomocą implementacji szyfru Cezara oraz AtBasha. Kod implementujący ten algorytm został napisany w języku ST.
Teoria
Szyfr AtBash
Szyfr AtBash, to wywodzący się z tradycji żydowskiej szyfr monoalfabetyczny, podstawieniowy.
Prawdopodobnie został on opracowany około roku 500 p.n.e.
Zasada działania:
Zasada jego działanie polega na podstawieniu zamiast jednej litery, litery leżącej po drugiej stronie alfabetu w takiej samej odległości od końca/początku.
Najłatwiej będzie wyjaśnić to na przykładzie:
Za literę `a' powinniśmy podstawić literę `z'. Natomiast za literę `c' literę 3 od końca alfabetu, a wiec literę `x'.
Warto zauważyć, że aby odszyfrować wiadomość należy ją ponownie zaszyfrować.
Otrzymamy tym samym tekst jawny.
Szyfr nie zapewnia bezpieczeństwa.
Szyfr Cezara (zwany też szyfrem przesuwającym, kodem Cezara lub przesunięciem Cezariańskim) - w kryptografii jedna z najprostszych technik szyfrowania. Jest to rodzaj szyfru podstawieniowego, w którym każda litera tekstu jawnego (niezaszyfrowanego) zastępowana jest oddaloną od niej o stałą liczbę pozycji w alfabecie inną literą (szyfr monoalfabetyczny), przy czym kierunek zamiany musi być zachowany. Nie rozróżnia się przy tym liter dużych i małych. Nazwa szyfru pochodzi od Juliusza Cezara, który prawdopodobnie używał tej techniki do komunikacji ze swymi przyjaciółmi.
Algorytm szyfrowania zastosowany w kodzie Cezara bywa fragmentem bardziej złożonych systemów szyfrowania, takich jak szyfr Vigenère'a. Współcześnie szyfru Cezara używa się z przesunięciem 13 (ROT13), będącego prostym i szybkim sposobem na ukrycie treści. Obecnie szyfr Cezara, jak każda technika podmieniająca pojedyncze litery alfabetu na inne, nie oferuje żadnego bezpieczeństwa komunikacji.
Projekt - informacje
User function bloki pozwalają użytkownikowi na stworzenie własnych bloków funkcyjnych rozwiązujących specyficzne zadania. Tworzenie UFB jest możliwe w drzewie projektu pod Function Block Pool P-FB. Każdy UFB jest identyfikowany przez klasę(FB-CLASS), która określa funkcjonalność oraz wygląd bloku. Klasa obejmuje program sterujący bloku składający się z funkcji, bloków funkcyjnych oraz zmiennych, a także faceplate oraz maskę parametrów.
Każda klasa posiada nazwę dzięki której poszczególne bloki mogą być wywoływane z innych programów.
Realizacja
Szyfr AtBash
W zrealizowanym projekcie utworzone została utworzona jedna FB-CLASS: szyfrująca i deszyfrująca o nazwie AtBash. Klasa posiada zdefiniowane w Interface editor zmienne wejściowe oraz wyjściowe oraz odpowiednie programy napisane w języku ST.
Zmienna In jest zmienną wejściową typu STR256 (string 256 znakowy) poddawaną szyfrowaniu. Zmienna Deszyfrowanie jest zmienną typu BOOL, określa zadanie bloku AdBash w danym momencie (szyfrowanie/deszyfrowanie). Zmienna Out jest zmienną wyjściową typu STR256 zawierającą zaszyfrowaną zmienna podaną na wejście.
Rys. Zmienne klasy AtBash
Kod w ST z komentarzami:
Szyfr Cezara :
FUNCTION_BLOCK konf_P
VAR_INPUT przesuniecie : INT; tekst : STR256; END_VAR
VAR_OUTPUT wyjscie : STR256; END_VAR
VAR (* PARA_DPS *) alfabet : STR256; END_VAR
(* PARA_VIS ClassName : TEXT; TagName : TEXT; ShortText : TEXT; LongText : TEXT; SelState : BOOL; END_VAR *)
VAR dlugosc, i, k : INT; lewy : INT; alfabetNowy : STR256; alfabetL, alfabetR : STR256; END_VAR; wyjscie := ''; dlugosc := S_LEN(tekst); alfabetNowy := ''; alfabetL := S_LEFT(alfabet, przesuniecie); alfabetR := S_RIGHT(alfabet, S_LEN(alfabet)-przesuniecie); alfabetNowy := S_CONCAT(alfabetR, alfabetL);
i := 1; WHIlE i <= S_LEN(tekst) DO k := S_FIND(alfabet, S_MID(tekst, 1, i)); wyjscie := S_INS(wyjscie, S_MID(alfabetNowy, 1, k), S_LEN(wyjscie)); i := i + 1; END_WHILE;
END_FUNCTION_BLOCK |
Pierwszym krokiem jest wyzerowanie zmiennej wyjście, aby nie przechowywała żadnych danych. Kolejny krok to wyznaczenie długości wprowadzonego przez nas tekstu jawnego. Następnie zerujemy zmienną alfabetNowy i wyznaczamy lewą, oraz prawą część alfabetu dzięki funkcji S_LEFT oraz S_RIGHT. Do pierwszej podajemy parametry alfabetu oraz przesunięcia (dzięki czemu wyznaczamy znaki, które mają znajdować się na końcu naszego nowego alfabetu).
Funkcja S_RIGHT pierwszy parametr przyjmuje taki sam jak w przypadku S_LEFT, natomiast drugi to różnica pomiędzy długością alfabetu, a przesunięciem.
Tak powstałe części łączymy przy pomocy funkcji S_CONCAT (parametrami tej funkcji są zmienna alfabetR i alfabetL), którą przypisujemy do zmiennej alfabetNowy. Dzięki temu wyznaczony mamy nowy alfabet z uwzględnieniem przesunięcia o pewien wektor w stosunku do oryginalnego alfabetu.
Kolejnym algorytmem jest przypisanie do zmiennej i wartości 1 i wywołanie pętli while z warunkiem i <= S_LEN(tekst), co pozwoli nam na przejście znak po znaku przez wprowadzony tekst i zamianę go.
Pierwszy krok w pętli jaki musimy wykonać to wyznaczenie pozycji aktualnego znaku z ciągu zmiennej tekst. Do tego celu używamy formuły polecenia S_FIND(alfabet, S_MID(tekst, 1, i)); Funkcja S_FIND pozwala nam w alfabecie odnaleźć odpowiedni znak. Aby ustalić ten znak używamy funkcji S_MID, do której przekazujemy jako pierwszy parametr zmienną tekst, następnie długość ciągu jaki nas interesuje (w naszym przypadku jest to wartość 1, ponieważ potrzebujemy tylko jednej literki), a jako trzeci parametr podajemy zmienną i, która informuje że szukana przez nas litera leży na i-tym miejscu w ciągu. Pozycja szukanej litery przechowywana jest w zmiennej k.
Następnie do zmiennej wyjscie przypisujemy wartość funkcji S_INS. Funkcja ta przyjmuje kolejno następujące parametry: pierwszy z nich to ciąg znaków do którego dodać chcemy kolejne znaki (w naszym przypadku jest to zmienna wyjście), drugi to znak ze zmiennej alfabetNowy, którą wyznaczamy przy pomocy funkcji S_MID. Dzięki podaniu jako 3 parametr zmiennej k otrzymujemy odpowiadający dla naszego przesunięcia znak z nowego alfabetu. Ostatni parametr funkcji S_INS to pozycja, w której wstawiamy dany znak. Chcąc wstawić go na ostatnie miejsce musimy użyć funkcji S_LEN, której jako parametr podajemy zmienną wyjście.
Dzięki tym operacjom otrzymujemy zakodowany tekst przy pomocy kodu Cezara.
Zmienne IN: przesuniecie INT, tekst STR256
Zmienne OUT: wyjście STR256.
PARA_DPS: alfabet STR256: podajemy na inicjalizacji cały alfabet
Funkcja deszyfrująca:
FUNCTION_BLOCK decod_P
VAR_INPUT przesuniecie : INT; tekst : STR256; END_VAR
VAR_OUTPUT wyjscie : STR256; END_VAR
VAR (* PARA_DPS *) alfabet : STR256; END_VAR (* PARA_VIS ClassName : TEXT; TagName : TEXT; ShortText : TEXT; LongText : TEXT; SelState : BOOL; END_VAR *) VAR dlugosc, i, k : INT; lewy : INT; alfabetNowy : STR256; alfabetL, alfabetR : STR256; END_VAR; wyjscie := ''; dlugosc := S_LEN(tekst); alfabetNowy := ''; alfabetL := S_LEFT(alfabet, przesuniecie); alfabetR := S_RIGHT(alfabet, S_LEN(alfabet)-przesuniecie); alfabetNowy := S_CONCAT(alfabetR, alfabetL);
i := 1; WHIlE i <= S_LEN(tekst) DO k := S_FIND(alfabetNowy, S_MID(tekst, 1, i)); wyjscie := S_INS(wyjscie, S_MID(alfabet, 1, k), S_LEN(wyjscie)); i := i + 1; END_WHILE;
END_FUNCTION_BLOCK |
Funkcja deszyfrująca działa w ten sam sposób co funkcja szyfrująca, jedyną różnicą jest zamiana zmiennej alfabet na afabetNowy w funkcji S_FIND, która przypisywana jest do litery k, a druga to zamiana zmiennej alfabetNowy na alfabet w funkcji S_MID używanej jako parametr funkcji S_INS.
Zmienne IN: przesuniecie INT, tekst STR256
Zmienne OUT: wyjście STR256.
PARA_DPS: alfabet STR256: podajemy na inicjalizacji cały alfabet.
Działanie przykładowego programu wykorzystującego stworzone UFB
Stworzone bloki są dostępne w menu Blocks>User function blocks…
AtBash:
Rys. Działanie bloku szyfrującego i deszyfrującego AtBash
Cezar:
Rys. Działanie bloku szyfrującego i deszyfrującego Cezar
Wnioski
Projekt został wykonany w języku ST w połączeniu z blokami FBD.
Zarówno AtBash jak i Cezar, są przykładami jednych z najprostszych algorytmów szyfrowania/deszyfrowania.
Algorytmy te nie zajmują dużo pamięci, oraz ich wykonanie jest bardzo szybkie.
Nie gwarantują one bezpieczeństwa w komunikacji.
Początkowym celem projektu, było zrealizowanie szyfrowania DES (Data Encryption Standard) , lecz brak czasu oraz umiejętności stworzenia go w języku FBD nie pozwoliły nam na to.
Problemem było wielokrotne i zarazem skomplikowane odwracanie macierzy, które w języku FBD jest trudne do zrealizowania.