[BSI] Kodowanie, hashowanie, szyfrowanie: Szyfrowanie

Część trzecia z czterech:

  1. Kodowanie.
  2. Hashowanie.
  3. Szyfrowanie.
  4. Przykłady zastosowań. Analiza istniejących rozwiązań.

3. Szyfrowanie – czyli 'zamiana tekstu jawnego w szyfrogram’, a w praktyce (nie wspominając o ZŁYCH praktykach) polega to na wykorzystaniu jakiejś funkcji matematycznej do przetworzenia 'czystego tekstu’ w 'bezsensowny bełkot’ z pomocą KLUCZA (hasła). W przeciwieństwie do 'hashowania’ ważne jest, aby ten proces dało się odwrócić (zamienic bełkot w początkowy tekst).
Głównym podziałem ze względu na zastosowanie jest podział na typ klucza/kluczy. Do wyboru mamy:
Algorytmy symetryczne (klucza prywatnego) – wykorzystują jeden klucz (hasło) do szyfrowania i odszyfrowywania
Algorytmy asymetryczne (klucza publicznego) – wykorzystują dwa klucze (między którymi istnieje pewna matematyczna zależność): publiczny do szyfrowania wiadomości i prywatny do odszyfrowywania, ważną cechą jest to, że z klucza szyfrującego (publicznego) nie da się utworzyć klucza deszyfrującego (prywatnego), więc jeśli da się komuś klucz szyfrujący (publiczny) i on nim zaszyfruje wiadomość to nikt po drodze nie będzie w stanie jej odczytać, bo tylko osoba która wygeneruje klucze ma klucz prywatny

Skąd nazwy symetryczne i asymetryczne? Zależą one od wykorzystanych w algorytmach funkcji:
Symetryczne to takie gdzie wykonuje się operacje odwrotną np. szyfrując `dodaje` się tyle do bajta ile wynosi wartość litery w KLUCZU (haśle), a odszyfrowując `odejmuje` się tą wartość (algorytmy: Rijndael [w wersji z 'blokami danych’ długości 128 bit zwany też ’AES’], DES [stary]).
Asymetryczne to takie gdzie do szyfrowania i odszyfrowywania wykonuje się inne operacje (i inne klucze, bo jest publiczny i prywatny) których działanie udowodnił jakiś matematyczny geniusz (algorytmy: RSA [wykorzystywany do szyfrowania połączeń do stron www, banków, między komputerami, w sieciach WiFi, … WSZĘDZIE], więc innych nie będę omawiał).

Co to jest szyfr blokowy (’bloki danych’)?
Szyfrowanie zazwyczaj polega na przestawianiu miejscami i zwiększaniu/zmniejszaniu wartości poszczególnych bajtów w przekazanym ciągu znaków. Większość algorytmów to szyfry blokowe – wymagają danych o określonej długości. np. AES przyjmuje dane w 'blokach danych’ o długości 128 bitów (16 bajtów), jeśli przekaże się mu dłuższy ciąg to podzieli go na 128 bitowe kawałki i każdy oddzielnie zaszyfruje, jeśli przekaże mu się ciąg krótszy to zależnie od implementacji danej funkcji/klasy AES w danym języku (często jest kilka do różnych zastosowań):
na końcu ciągu doda zera (NULL) – stosowane gdy niskie opóźnienie jest ważniejsze od ilości przesłanych danych = chcemy uzyskać zaszyfrowany ciąg natychmiast po przekazaniu danych (wada: przesłanie 1 znaku wykorzysta 16 znaków (128bit), marnując resztę na zera), stosowane np. w grach online (mało gier korzysta z szyfrowania ze względu na opóźnienia)
[nie zawsze na końcu są dodawane zera, czasem inne ustalone wcześniej wartości 'dopełniania bloku danych’, więcej na ten temat: http://en.wikipedia.org/wiki/Padding_%28cryptography%29 ]
nie zrobi nic – będzie czekał, aż przekażemy kolejne znaki i będzie ich w sumie 128 bit – wymagane przy szyfrowaniu pliku, kiedy odczytujemy plik 'czysty’ i zapisujemy używając AES, ilość danych zapisanych powinna być jak najmniejsza, więc lepiej poczekać, aż się plik skończy (program wywoła na pliku funkcje np. 'plik.close()’) i wtedy zapisać ostatni 'blok’ z zerami na końcu (NULLami), niż co chwilę na dysk zrzucać kolejne bloki kończąc je zerami (zakładając typowy algorytm kopiowania 'odczytaj 100 bajt -> zapisz 100 bajt -> sprawdź czy koniec pliku odczytywanego’)

Co to jest 'CBC’, 'Block cipher mode of operation’, 'Tryb wiązania bloków zaszyfrowanych’?
Tryby wiązania bloków są różne, ale do praktycznych (bezpiecznych) zastosowań wykorzystuje się 'CBC’ (Cipher-block chaining). Na pewno przemawia za tym fakt, że w wielu językach programowania oprócz trybu CBC nie ma innych, a czasem nie ma nawet możliwości wyboru trybu tylko gdzieś w dokumentacji jest notatka, że dana biblioteka korzysta z trybu CBC. Jak działa CBC?
CBC to tryb który nie pozwala na szyfrowanie wielowątkowe, ale można odszyfrowywać wielowątkowo (na kilku rdzeniach, a nawet wielu komputerach naraz). Nie da się szyfrować pliku w kilku wątkach naraz, bo aby zaszyfrować blok danych (te wspominane wcześniej 128 bitów) trzeba znać wynik zaszyfrowania poprzedniego bloku. Po co? Zanim zacznie działać algorytm mieszania tablicy bajtów w pamięci (szyfrowania bloku [dla AES – 16 bajtowej tablicy]) ta pamięć (RAM) musi mieć jakąś wartość. Jaką? Najprościej było by dać tam zawsze same NULLe i po sprawie nie? Jednak geniusze wymyślili, że lepiej będzie tam przypisać jakieś wartości pseudo-losowe, a skąd wziąć wartości pseudo-losowe które przy szyfrowaniu i odszyfrowywaniu będą takie same, a za razem inne dla każdego bloku? Z poprzedniego zaszyfrowanego bloku! W tym momencie dochodzimy do czegoś co nazywa się IV..
(Odszyfrowywanie w wielu wątkach jest możliwe, bo można do wątku nr X przekazać, że ma odszyfrowywać dane od 1500 bloku korzystając z wartości zaszyfrowanego bloku 1499 jako IV.)

Co to jest IV (Initialization vector)?
Jest to ciąg znaków o długości równej blokowi danych danego algorytmu (128 bit dla AES). Wykorzystuję się go w większości trybów szyfrowania (np. we wspomnianym wyżej CBC). Jest to wartość tablicy 'mieszającej’ trzymanej w pamięci RAM. Za wartość tą bierze się ciąg znaków poprzedniego zaszyfrowanego bloku (w trybie CBC), ale co z pierwszym blokiem? Nie ma bloku 'zero’ z którego można by wziąść wartości do ustawienia w tablicy mieszającej. Wtedy właśnie bierze się wartość IV! Blok IV nie zawiera w sobie żadnych informacji – dla tego można go dodać do danych zaszyfrowanych. Najpopularniejszą praktyką jest dodanie go przed danymi zaszyfrowanymi. Skoro ma 16 znaków (w AES) to wystarczy tylko pamiętać, że zawsze kiedy bierzemy jakieś dane do odszyfrowania musimy odczytać 16 znaków i przekazać je do 'decryptora’ jako blok IV (funkcje typu 'mojDekryptor.setIv(pierwsze16znakow);’, a reszte znaków (do 16 do końca) przekazać jako zaszyfrowane dane.
Bardzo ważne jest, aby blok IV zawsze był inny (pseudo-losowy)! Inaczej ułatwiamy atak mający na celu odszyfrowanie danych (szczególnie kiedy mamy miliony zaszyfrowanych danych, np. dla wszystkich plików na dysku używamy jednego IV).
Co jeszcze nam daje IV? Jeśli ten sam ciąg znaków np. 'ala ma kota’ zaszyfrujemy używając innego IV to zaszyfrowany blok danych będzie inny. Dzięki temu hacker nie ma szans sprawdzić czy 2 pliki są identyczne na podstawie ich zaszyfrowanej wersji danych.
Blok IV można też traktować jako 'drugą część hasła’ (i przekazywać 'tajnie’, a nie dołączać do pliku), bo nie posiadając bloku IV nie można odszyfrować danych nawet znając hasło. Jednak nie znalazłem nigdzie informacji czy 'odkrycie’ IV jest tak samo trudne jak hasła do zaszyfrowanych danych.

Omówienie 2 najpopularniejszych szyfrowań:
AES (Advanced Encryption Standard) – szyfr blokowy, symetryczny (klucz prywatny), o blokach danych długości 16 znaków i kluczach (hasłach) długości 16, 24 lub 32 znaków, do zaszyfrowania danych trzeba wylosować IV i hasło, jeśli hasło ma być 'dla ludzi’ np. 'ala ma kota’, to można wykorzystać jakąś funkcje hashująca która po wpisaniu przez użytkownika hasła wygeneruje ciąg pseudo-losowy [pseudo, bo zależy od tego co wpisze użytkownik] o odpowiedniej długości.
Zastosowania:
– szyfrowanie plików (dość szybkie szyfrowanie dużych ilości danych)
– szyfrowanie danych kiedy hasło ma być czytelne dla ludzi – można samemu ustalić hasło

RSA – szyfr blokowy, asymetryczny (klucz publiczny), o blokach danych zależnych od długości klucza (11 znaków krótszych od klucza), aktualnie używa się kluczy o długości od 1024 do 4096 bitów (128 znaków do 512 znaków z czego 'dla Ciebie’ jest od 117 do 501 znaków), ze względu na dość wolne działanie wykorzystywany zazwyczaj jako algorytm do szyfrowania 'kluczem publicznym’ hasła (klucza prywatnego [czasem także IV]) algorytmu AES. Wyjątkową cechą RSA jest to, że korzystając z tego algorytmu można nie tylko szyfrować/deszyfrować wiadomości, ale także 'podpisywać’ i 'sprawdzać podpis’ cyfrowy.
Najwięcej czasu w typowym zastosowaniu algorytmu zajmuje wygenerowanie klucza publicznego i prywatnego, składają się one z 3 liczb: 'n’, 'e’ i 'd’.
Klucz publiczny (do szyfrowania, sprawdzania podpisu) składa się z 'n’ i 'e’.
Klucz prywatny (do odszyfrowywania, tworzenia podpisu) składa się z 'n’ i 'd’. Czasem razem z kluczem prywatnym zapisuje się też 'e’ tak, aby móc w przyszłości przekazać komuś klucz publiczny. Jednak w normalnych zastosowaniach klucz publiczny należy przekazać ustalonej osobie/maszynie, a potem zapomnieć i przechowywać tylko klucz prywatny (’n’ i 'd’).
Ważną cechą algorytmu RSA jest to, że oprócz oczywistej w kryptografii klucza publicznego nie możliwości odtworzenia klucza prywatnego na podstawie publicznego, nie możliwe jest też odtworzenie klucza publicznego na podstawie prywatnego [zapisanego bez liczby 'e’].
Zastosowania:
– szyfrowanie klucza algorytmu AES (kiedy jest potrzebna kryptografia 'klucza publicznego’, a zarazem do przesłania jest dużo danych)
– podpis cyfrowy (e-maile, pliki, a także potwierdzanie 'tożsamości’ przez strony www banków i firm – wszystko to się opiera na generowaniu i wymianie wielu kluczy publicznych przez komputery)
Wady:
– wolne działanie – mimo, że to algorytm blokowy, zazwyczaj wykorzystuje się tylko jeden blok (zaszyfrowany klucz [+IV?] do algorytmu AES – 16-48 znaków)
– stosunkowo dużo (do 8 procent!) dodatkowych danych zapisywanych w zaszyfrowanych blokach danych
– 'hasła’ (klucze) są generowane losowo i składają się z ciągów setek cyfr – nie do zapamiętania/wpisania dla człowieka
Teraz pora na trochę przykładów z życia z Bob’em i Alice:

AES – Bob chce nagrać na pendrive plik dla Alice, ale w przypadku zgubienia pendrive znalazca nie może mieć dostępu do pliku:
1. Bob losuje hasło, szyfruje plik algorytmem symetrycznym AES i nagrywa na pendrive.
2. Bob daje Alice pendrive.
3. Bob wysyła do Alice SMS z hasłem do pliku.
4. Alice odszyfrowuje plik używając algorytmu AES i hasła jakie dostała od Boba.
Podsumowanie: aby przejąć plik ktoś musiał by mieć pendrive i telefon Alice (lub inną rzecz jeśli hasło zostało by przesłane inną drogą)

RSA – Bob chce wysłać tajną wiadomość do Alice którą nawet jak ktoś podejrzy to nie będzie mógł odczytać.
(Rozwiązanie przykładowe, nie nadaje się do implementacji ze względu na podatność na pewne ataki):
1. Bob prosi Alice o przysłanie e-mailem wylosowanego klucza publiczenego RSA.
2. Alice losuje klucz publiczny i prywatny RSA, a potem publiczny wysyła do Boba.
3. Bob szyfruje swoją wiadomość algorytmem RSA używając klucza publicznego Alice.
4. Bob wysyła zaszyfrowany bełkot do Alice.
5. Alice odszyfrowuje wiadomość używając klucza prywatnego.
… taka jest teoria …

PROBLEM 1:
W rzeczywistości 'listonosz’ może wziąć klucz publiczny Alice który miał przekazać do Boba i zaszyfrować co chce używając tego klucza. Potem może wysłać taka wiadomość do Alice podpisując się 'Bob’. W ten sposób Alice dostanie wiadomość zaszyfrowaną kluczem 'który ma Bob’, a napisaną przez kogoś innego.

PROBLEM 2 (poważniejszy):
1. 'listonosz’ zapisuje 'klucz publiczny Alice’, samemu generuje nową parę kluczy RSA i przekazuje 'swój’ klucz publiczny do Boba mówiąc, że to od Alice
2. Bob szyfruje swoją wiadomość kluczem 'listonosza’ (nie Alice!) i oddaje mu, żeby ją przekazał Alice
3. 'listonosz’ odszyfrowuje wiadomość, bo przecież to jego (listonosza!) klucz prywatny jest do tego potrzebny
4. 'listonosz’ odczytuje wiadomość i szyfruje ją za pomocą klucza publiczego który dała mu Alice
5. 'listonosz’ daje Alice wiadomość od Boba (lub inną którą sam napisze!)
Wynik: listonosz zna treść listu, listonosz może podmienić treść listu, Alice i Bob nie mają o niczym pojęcia, mimo mocnego szyfrowania osoba 'po środku’ (odpowiedzialna za komunikację) może robić co chce z wiadomościami

Atak tego typu nazywa się ’Man in the middle’ ( http://pl.wikipedia.org/wiki/Atak_man_in_the_middle ), występuje we wszystkich protokołach 'klucza publicznego’ i jest nie do uniknięcia. Jak OGRANICZYĆ możliwość takiego ataku opiszę w części czwartej (organizacje certyfikujące / wykorzystanie innych dróg komunikacji [e-mail, sms …] / tokenizery).

———————————–
Listonosz [nasz zły bohater z opowieści o Alice i Bobie] to ktoś kto wepnie się w łącze internetowe/przeglądarkę internetową/włamie do telefonu i będzie 'filtrował’ ruch zmieniając przesyłane treści – przykłady: NSA/dostawca internetu/pracodawca/hacker/dzieciak rozsyłający trojany itp.

Ten wpis został opublikowany w kategorii PJWSTK - BSI. Dodaj zakładkę do bezpośredniego odnośnika.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *