W dzisiejszych czasach składnikiem niemalże każdego systemu informatycznego jest jego architektura bezpieczeństwa. Powinna się ona rozwijać od początku projektowania systemu i stanowić z nim integralną całość. W przeciwnym wypadku często okazuje się, że w już działającym systemie trudno wprowadzić zabezpieczenia bez naruszania fundamentów jego architektury. Z moich obserwacji wynika, że umiejętność zrozumienia i poprawnego określenia co i w jaki sposób chcemy chronić jest niezbędna, aby tworzone rozwiązanie nie zmieniło się w *kryptograficznego potworka, nad którym po kilku tygodniach nikt nie panuje. Tematem tego wpisu są techniki zabezpieczania informacji pokazane od podszewki, czyli od strony podstawowych usług, które realizują ten cel.
Kryptografia i kryptoanaliza
Nauką, która zajmuje się zabezpieczaniem informacji, jest kryptologia. Dzieli się ona na kryptografię oraz kryptoanalizę. Kryptografia jest nauką o konstruowaniu bezpiecznych systemów ochrony informacji, kryptoanaliza zajmuje się ich łamaniem. Kryptologią zajmuje się kryptolog, kryptografią --- kryptograf, a kryptoanalizą --- kryptoanalityk.
Można pomyśleć, że kryptoanalitycy to ci niedobrzy, którzy niszczą zabezpieczenia wymyślone przez kryptografów. Jednak to właśnie dzięki nim mamy coraz lepsze algorytmy. Kryptoanalitycy wymuszają na kryptografach tworzenie kolejnych bezpieczniejszych rozwiązań odpornych na odkrywane ataki. Obecnie jedni bez drugich nie mają racji bytu i są równie ważni w procesie przygotowania i sprawdzenia algorytmu kryptograficznego. W praktyce każdy kryptograf powinien być również kryptoanalitykiem, ponieważ w pierwszym kroku sam musi przeprowadzić kryptoanalizę proponowanego algorytmu.
Nie tylko szyfrowanie
Ochrona informacji kojarzy się głównie z pojęciem poufności (ang. confidentiality). Jest to usługa mająca na celu takie zabezpieczenie danych, aby nie były ujawnione nieuprawnionym jednostkom. Realizowana jest najczęściej za pomocą algorytmów szyfrujących (ang. encryption algorithm), w których dostęp do zabezpieczonych danych możliwy jest wyłącznie podmiotom znającym tajny klucz (ang. secret key).
Poufność jest jedną z czterech podstawowych usług ochrony informacji. Trzy pozostałe to integralność, uwierzytelnienie i niezaprzeczalność.
Usługa integralności (ang. integrity) realizuje funkcję, która polega na zapewnieniu, że przetwarzana informacja nie została w żaden sposób zmieniona. Zmiana taka może być przypadkowa (błąd transmisji) jak i celowa (zmiana przez atakującego). Do zapewnienia integralności danych w kryptografii stosuje się kryptograficzne funkcje skrótu (ang. cryptographic hash function).
Uwierzytelnienie (ang. authentication) jest procesem, którego celem jest stwierdzenie, że zadeklarowana cecha danego podmiotu jest prawdziwa. Brzmi to nieco enigmatycznie. W przypadku uwierzytelniania osoby będzie to proces, który potwierdzi np. jej tożsamość. Dzięki temu będziemy wiedzieli z kim się komunikujemy. Uwierzytelnianiu podlegają nie tylko osoby, ale również systemy, źródła danych czy dokumenty. Do realizacji usługi uwierzytelnienia stosuje się w kryptografii między innymi hasła (ang. password), kody uwierzytelniające wiadomość (ang. message authentication code, MAC) oraz podpis cyfrowy (ang. digital signature).
Niezaprzeczalność (ang. non-repudiation) to brak możliwości wyparcia się uczestnictwa podmiotu w procesie wymiany danych. Jest to usługa kosztowna w realizacji ponieważ wymaga gromadzenia danych w celach dowodowych oraz uczestnictwa zaufanej strony (ang. trusted third party). Do jej realizacji wykorzystuje się miedzy innymi podpis cyfrowy oraz znaczniki czasu (ang. timestamp), które są dowodem na istnienie danych w określonym czasie. Dlaczego podczas komunikacji między dwiema jednostkami, które się komunikują potrzebna jest trzecia zaufana strona? Wyobraźmy sobie sytuację podpisania umowy pomiędzy dwiema stronami. Każda z nich przechowuje kopię dokumentu z podpisem. Jeśli jedna ze stron zechce oszukać drugą po prostu zniszczy swoją kopię i będzie starała się dowieść, że umowy nie było. Taki atak się nie powiedzie --- druga strona wyciągnie swoją kopię dokumentu z podpisem. Nieco inaczej sytuacja będzie wyglądała gdy obie strony dojdą do porozumienia, że lepiej jest dla nich zlikwidować umowę. Bez zaufanej trzeciej strony przechowującej jej kopię niezaprzeczalność w takim systemie będzie do podważenia.
Wymienione usługi ochrony informacji nie są zupełnie niezależne od siebie. Szczególną rolę pełni usługa integralności, ponieważ bez niej nie ma możliwości prawidłowej realizacji pozostałych usług. Przykładowo zapewnianie poufności bez zapewnienia integralności to błąd występujący w wielu systemach. Algorytmy szyfrujące działają tak, że dowolne dane można rozszyfrować. Odrębnym pytaniem jest czy to co otrzymamy ma sens. A jak to jednoznacznie sprawdzić, kiedy integralność nie jest zapewniona?
Jakie zabezpieczenia wybierać
Nim wybierzemy zabezpieczenia musimy sobie odpowiedzieć na pytanie jakie dane i którymi technikami chcemy chronić. Czy konieczna jest zapewnienie poufności? Może wystarczy integralność i uwierzytelnienie? Które z procesów mają spełniać warunek niezaprzeczalności?
Od strony doboru konkretnych algorytmów istnieją ogólniejsze zasady wyboru zabezpieczeń. Przedstawił je Auguste Kerckhoffs w artykule La cryptographie militaire, który ukazał się w roku 1883 w czasopiśmie Journal des sciences militaires. Choć dotyczą usługi poufności i mimo że minęło już ponad 130 lat od ich opublikowania są wciąż aktualne. Dziś nie należy odczytywać dosłownie ich znaczenia. Choćby dlatego, że maszyny szyfrujące zostały zastąpione algorytmami, które nie zajmują już pół wagonu w pociągu.
Auguste Kerckhoffs zauważył, że system będzie użyteczny i praktycznie nie do złamania jeśli spełnione zostaną poniższe warunki:
- budowa maszyny będzie jawna, tajny jest wyłącznie klucz --- tłumacząc na dzisiejszy język w systemach wykorzystujemy jawne algorytmy, tajny powinien być tylko klucz,
- klucz jest łatwy do zapamiętania,
- kryptogram, czyli zaszyfrowane dane są łatwe do przekazania,
- maszyna szyfrująca jest podręczna,
- system jest prosty w użyciu.
Kluczowa dla dzisiejszych systemów jest pierwsza zasada. Nie tworzymy rozwiązań, których bezpieczeństwo opiera się na ukryciu, utajnieniu rozwiązania, wykorzystaniu nieznanego algorytmu (ang. security by obscurity). Praktyka pokazuje, że takie systemy są zazwyczaj łamane. Używamy wyłącznie jawnych, sprawdzonych algorytmów w prawidłowy sposób (ang. security by design).
Podsumowanie
Nie zawsze musimy zabezpieczać wszystkich i wszystko. Poza tym, że to kosztuje, to takie rozwiązanie w efekcie prowadzi do systemu, który jest skomplikowany i trudniejszy w użyciu. Typowy użytkownik nie lubi rzeczy trudnych i jego naturalnym podstępowaniem będzie mniej lub bardziej udana próba obejścia zabezpieczeń. W ten sposób zbyt duże wymagania względem bezpieczeństwa mogą prowadzić do jego obniżenia. Paradoks wynikający z naszej ludzkiej i nieco leniwej natury.
Jeśli już wdrażamy zabezpieczenia to musimy robić to poprawnie. Podstawową zasadą jest zapewnienie integralności przy wdrażaniu innych usług. W przeciwnym razie nie mają one sensu. Nie ma nic gorszego niż nieprawidłowe użycie dobrych algorytmów kryptograficznych. Trzeba pamiętać, że złudne poczucie bezpieczeństwa jest gorsze od prawdziwego pojmowania niebezpieczeństwa.
Nie ma praktycznie działających systemów nie do złamania. Zabezpieczenia trzeba dobrać tak, żeby atakującemu nie opłacało się ich łamać. Nie są to łatwe decyzje. Niekiedy mówi się, że z trzech rzeczy: tani, szybki i bezpieczny można wybrać tylko dwie.
W kolejnych wpisach dokładniej omówię wymienione usługi ochrony informacji wraz z współczesnymi algorytmami jakie je realizują. Pokażę również jak stosować je w praktyce na platformie Java.