Parę słów o szyfrowaniu i bezpieczeństwie


Jak przekazać bezpiecznie login, hasło i treść? Poniższy tekst przedstawia główne mechanizmy wykorzystywane do bezpiecznej komunikacji. Ogólną zasadę działania szyfrowania symetrycznego i związek z generatorem liczb pseudolosowych, funkcję skrótu (hash) oraz zasadę działania i wykorzystanie szyfrowania asymetrycznego w protokołach hybrydowych.

Symetryczne szyfrowanie danych

Szyfrowanie odbywa się z wykorzystaniem binarnej operacji XOR. Dane źródłowe XOR-owne są z pewną liczbą bajt po dajcie. Jeśli byłaby to tylko jedna liczba z zakresu 1-255, to wystarczyłoby przeprowadzić parę razy test i najpóźniej za 255-tym razem otrzymalibyśmy rozszyfrowaną wiadomość (niektóre pliki avi w ten sposób są szyfrowane). Jeśli każdy kolejny bajt byłby XOR-owany z inną liczbą, to znalezienie odpowiedzi nie byłoby już takie łatwe.

Te inne liczby najlepiej aby były losowe, a nie wyliczane (np, na zasadzie następna=poprzednia+1), obie strony, nadawca i odbiorca zaszyfrowanej wiadomości, muszą jednak mieć listę tych liczb. Do tworzenia takiej listy najlepiej nadają się generatory liczba pseudolosowych. Pseudolosowych dlatego, że kolejne wartości nie są tak naprawdę losowe, lecz są obliczane. Zainicjowane pewnym ziarnem (seed) zawsze dają te same kolejne wartości. Zatem jeśli nadawca i odbiorca znają ziarno i algorytm generowania liczb, mogą wyliczyć kolejne wartości listy z której pobierane są dane do operacji XOR. (wikipedia-symetryczny szyfr strumieniowy)

Szyfrowanie nazywane jest symetrycznym, ponieważ znając klucz szyfrujący możemy nim zarówno zakodować jak i zdekodować treść. W tym przypadki kluczem jest ziarno generatora liczb pseudolosowych.

Generator liczb pseudolosowych

Kolejne wartości generatora liczb pseudolosowych mogą być wyliczane następująco (szczegóły tutaj, tutaj i tuxi = (a * xi-1 + c) mod m

  • xi i-ta wygenerowana liczba pseudolosowa
  • a współczynnik generujący kolejną liczbę pseudolosową
  • m współczynnik określający zakres generowanych liczb pseudolosowych (od 0 do m-1)
  • c stała, np 1

x1 jest początkową wartością, którą inicjuje się generator – tzw. ziarnem (ang. seed)

Przykładowo:
GNU Compiler Collection (gcc) posiada wartości: m=232, a=69069, c=5;
MAPLE m=1012-11, a=427619669081, c=0;
JAVA m=248, a=25214903917, c=11

  • m powinno być duże, często wybiera się tutaj potęgi 10 albo 2, musi być liczbą pierwszą bądź jej wielokrotnością
  • a nie powinno być zbyt duże, ale też nie za małe – dobrym wyborem jest tutaj liczba o jeden rząd mniejsza (o jedną cyfrę krótsza) od m,
  • a musi być pierwiastkiem pierwotnym modulo m, czyli dla dowolnego b takiego, że NWD(b, m) = 1 istnieje liczba całkowita k taka, że ak mod m = b
  • x0 musi być względnie pierwsze z n,czyli NWD(x0, n) = 1

Jeżeli kolejna wygenerowana liczba powtarza się w ciągu liczb już wygenerowanych to wpadamy w cykl. Źle dobrane wartości mogą prowadzić do wygenerowania bardzo krótkich cykli np: dla b=19, m=381 oraz x1=0 otrzymamy sekwencję: 0, 1, 20, 0, 1, 20, …

Aby otrzymać liczbę z przedziału [a,b] nie należy modyfikowac parametrów generatora a jedynie użyć operacji modulo: liczba losowa = a + (rand() mod (b-a+1))

Podstawą bezpieczeństwa jest generator dający możliwie najdłuższy niepowtarzający się ciąg liczb.

Haszowanie danych – funkcja skrótu

Zadaniem funkcji skrótu (hash) jest wygenerowanie skrótu danych wejściowych, który jednoznacznie określa dane a jednocześnie nie pozwalają na odtworzenie pierwowzoru. Jednym z algorytmów jest MD5. Dzięki temu można zapamiętywać hasła (ich skróty) bez obawy, że osoba która je widzi pozna treść hasła, lub też sprawdzić czy ściągnięty plik nie zawiera błędów (skrót ściągniętego jest taki sam jak podany 32 znakowy MD5).

Algorytmy skrótu mają niestety swoje słabości. Za pomocą tablic tęczowych (Rainbow Tables) można znacznie przyspieszyć łamanie haseł metodą „brute force”. Szczegóły tutaj (oryginał tu)

Aby zabezpieczyć się przed tym należy „posolić”  hasło przed haszowaniem, czyli dodać pewien ciąg znaków np: md5( $passwd . $salt ); (więcej: tutaj)

Skróty haseł najlepiej przechowywać w bazie danych. Wykorzystanie sesji php nie jest dobrym rozwiązaniem gdyż dane przechowywane są w plikach (to tak ogólnie).

Logowanie

Co należy powyłączać, komu co pozwolić opisano tutaj.  Jeśli nie używamy HTTPS (SSL),  to dane są przesyłane jawnie, czyli login i hasło można namierzyć snifferem i przeczytać sobie. I to tyle jeśli chodzi o bezpieczne przesyłanie hasła.

Sesje

HTTP jest protokołem bezstanowym, zatem teoretycznie za każdym razem należałoby podać dane do autoryzacji (login, hasło). Po zalogowaniu można utworzyć tzw. sesję i przekazać jej numer użytkownikowi. Numer musi być w z bardzo dużego przedziału, aby trudno było go zgadnąć.  W kolejnych żądaniach nie podaje się hasła, a tylko numer sesji. Sesje (ich numery), tak jak hasła, lepiej w bazie danych trzymać. Nadal istnieje zagrożenie, że numer sesji zostanie przechwycony. Dlatego warto sprawdzać dodatkowe dane takie jak numer IP i przeglądarka (user agent) i związywać je z daną sesją. Wówczas podszycie się wymagałoby również „udawanie” adresu IP itd.

Przechwycenie sesji jest mniej szkodliwe o tyle, że po wygaśnięciu sesji (np po wylogowaniu lub po upływie czasu) już nie można jej używać.

Szyfrowanie asymetryczne

Do szyfrowania i deszyfrowania wykorzystywane są dwa klucze: klucz publiczny e (jawny i powszechnie dostępny) oraz klucz prywatny d (pilnie strzeżony). Są one ze sobą powiązane i niemożliwe do odtworzenia jednego za pomocą drugiego. Jeden z kluczy używany jest do szyfrowania wiadomości (e), drugi do deszyfrowania (d). Zasada działania polega na wykorzystywaniu operacji, które są proste do wykonania w jedną stronę, a bardzo trudne i czasochłonne do wykonania w drugą stronę. (wiki: kryptografia asymetryczna)

Osoba A wysyłająca treść do do osoby B, szyfruje ją kluczem publicznym e osoby B. Następnie osoba B deszyfruje wiadomość swoim kluczem prywatnym d. Nawet przechwycenie wiadomości i znajomość klucza publicznego nie pozwoli na odszyfrowanie. (więcej tutaj)

Podpis cyfrowy

W algorytmie RSA istnieje możliwość zamiany kluczy. Osoba chcąca podpisać cyfrowo publikowaną przez siebie treść wylicza skrót tej wiadomości (hash). Następnie szyfruje ten skrót używając tym razem klucza prywatnego (d) (inaczej niż poprzednio służącego do deszyfrowania). Dołącza wynik do wiadomości (jako podpis).

Osoba chcąca sprawdzić autentyczność wiadomości, deszyfruje dołączony skrót kluczem publicznym (e) potencjalnego autora. Następnie sama wylicza skrót treści i porównuje wynik z tym, który zdeszyfrowała.

Protokoły hybrydowe

Proces szyfrowania i deszyfrowania jest czasochłonny zatem kryptografia asymetryczna stosowana jest jedynie do przekazania klucza (np seed generatora liczb pseudolosowych) wykorzystywanego dalej do szyfrowania symetrycznego. Ogólnie proces przebiega następująco:

  • klient uzyskuje klucz publiczny serwera (np od zaufanej firmy certyfikującej lub inaczej bezpiecznie przekazanego abyśmy mieli pewność, że to właśnie klucz tego serwera)
  • klient generuje klucz sesyjny (np. seed) dla szyfrowania symetrycznego
  • klucz sesyjny jest szyfrowany kluczem publicznym serwera i przesyłany do serwera
  • serwer deszyfruje wiadomość z użyciem klucza prywantego i otrzymuje klucz sesyjny.
  • Dalsza komunikacja przebiega już z zastosowaniem szyfru symetrycznego

W ten sposób login i hasło można już bezpiecznie przekazać w zaszyfrowanym kanale. Protokół hybrydowy wykorzystywany jest w https, ssl, ssh (na jakilinux.org jest fajny artykuł o wykorzystaniu ssh).

, , , , , ,

Komentarze nie są dozwolone.