SSL - Teoria i zasada działania
I Podstawy kryptografii
Algorytmy szyfrowania danych dzielimy najczęściej na dwa rodzaje w
zależności od używanego schematu kluczy danych. Pierwszy rodzaj to
1. Kryptografia kluczy prywatnych
Ten sposób szyfrowania danych (zwany również kryptografią
symetryczną, lub kryptografią z kluczem tajnym} znany
jest od dawna. Najprostsze jego rodzaje to szyfry oparte o
przestawianie liter według pewnego, z góry ustalonego schematu.
Dane szyfrowane były w ten sposób już w starożytności - np.
Juliusz Cezar używał szyfru opartego na tym schemacie do
przekazywania rozkazów swoim oddziałom.
Ogólny schemat wszystkich tego typu algorytmów jest
następujący:
- Strony uzgadniają klucz(e) służące do
szyfrowania/deszyfrowania danych.
(Najczęściej ten sam klucz służy zarówno do szyfrowania jak i
deszyfrowania, ale nie jest to regułą).
- W późniejszym czasie strony używają
uzgodnionych kluczy do wymiany danych, ewentualnie zmieniając je
co jakiś czas.
Bardziej zaawansowane szyfry symetryczne używane dzisiaj opierają
się o operacje na bitach. Najbardziej znany algorytm to
DES używany m.in. do szyfrowania haseł w systemach
UNIX-owych. Używa on skomplikowanych operacji na bitach danych,
których kolejność i rodzaj zależy właśnie od bitów klucza. Inne
znane algorytmy symetryczne to 3DES (mocniejsza wariacja
DES, RC2 i RC4.
Największą zaletą algorytmów symetrycznych jest ich
szybkość - odpowiednio stosowane, mogą tylko nieznacznie
zmniejszać przepustowość kanału transmisyjnego.
2. Kryptografia kluczy publicznych
Odkrycia matematyczne drugiej połowy XX wieku umożliwiły powstanie
kryptografii opertej o klucze publiczne. Podstawową wadą szyfrów
symetrycznych jest bowiem konieczność uzgodnienia a priori tajnych
kluczy używanych do wymiany danych. Często stawia to pod znakiem
zapytania cały sens operacji, jeżeli np. strony znajdują się w
dużym oddaleniu od siebie i potrzebują przesłać pilne dane.
Taka sytuacja wprowadzała poza tym problem związany
z tajnością kluczy. Aby bowiem dwie strony mogły uzgodnić ze sobą
tajne klucze, musiały najpierw przesłać je sobie drogą
tajną - ale jak przesłać zaszyfrowane klucze nie mając
kluczy używanych do szyfrowania?
Kryptografia kluczy publicznych, zwana
także kryptografią asymetryczną zakłada, że każda transmisja
danych używa dwóch kluczy. Jeden z nich, klucz prywatny
znany jest tylko jednej stronie, zaś drugi, klucz
publiczny, nie musi być tajny - jest on powszechnie dostępny i
umożliwia przykładowo wysyłanie zaszyfrowanych informacji do
właściciela klucza prywatnego.
Matematyczne podstawy kryptografii asymetrycznej
oparte są o "problemy asymetryczne", czyli takie, które jest o
wiele łatwiej wymyśleć, niż rozwiązać. Typowy przykład to
faktoryzacja liczb - łatwo jest pomnożyć przez siebie kilka dużych
liczb pierwszych, natomiast rozkład iloczynu na czynniki jest już
dużym problemem obliczeniowym.
Ogólny schemat działania metod szyfrowania z kluczem
publicznym jest następujący:
- Każda ze stron generuje parę kluczy (publiczny+prywatny)
- Każda ze stron publikuje swój klucz publiczny w sieci (jest
on dostępny dla wszystkich)
- Jeżeli A chce przesłać wiadomość do B to szyfruje
ją kluczem publicznym B. Z własności algorytmu wynika, że
tylko używając klucza prywatnego B można ją odtworzyć
(to jest typowy schemat wymiany danych).
- Jeżeli B chce mieć pewność, że wymienia informacje
rzeczywiście z A, to może np. poprosić A o zaszyfrowanie pewnego
tekstu jego kluczem prywatnym. Jeżeli B będzie w stanie
odtworzyć tekst używając klucza publicznego A to znaczy,
że rozmawia rzeczywiście z właściwym partnerem.
(to jest typowy schemat autentyfikacji partnera)
- Jeżeli B po odebraniu wiadomości od A chce zabezpieczyć się
przed sytuacją, w której A zaprzeczy, że wysłał wiadomość, może
poprosić A o zaszyfrowanie jej dodatkowo swoim kluczem
prywatnym (a następnie kluczem publicznym B). B będzie w
stanie ją odszyfrować (najpierw używając swojego klucza
prywatnego, a następnie publicznego klucza A) i A nie będzie mógł
zaprzeczyć, że wiadomość wysłał - wiadomość która dała się
odszyfrować kluczem publicznym A musiała być zaszyfrowana jego
kluczem prywatnym.
(to jest typowy schemat podpisu cyfrowego)
Najbardziej znany przykład algorytmu stosującego klucze publiczne
to RSA stosowany np. w systemie bezpiecznej poczty PGP.
Jak widać kryptografia asymetryczna likwiduje
wszystkie wady kryptografii symetrycznej. Jest to właściwie
rozwiązanie doskonałe, które ma tylko jedną wadę: szybkość. O ile
algorytmy symetryczne (zwłaszcza blokowe) dobrze nadają się do
stosowania "w locie", to złożoność obliczeniowa szyfrowania czy
deszyfrowania z użyciem kluczy publicznych raczej wyklucza takie
zastosowania. Próbą połączenia najlepszych cech obydwu metod
szyfrowania jest
3. Metoda mieszana
Najważniejszym faktem dla tej metody stała się obserwacja, że
niedogodność algorytmów symetrycznych nie polega na ich "słabości"
- dobierając odpowiednio długi klucz możemy uzyskać zabezpieczenie
właściwie dowolnie "silne". Problemem jest tylko uzgodnienie tych
kluczy. Za to algorytmy symetryczne są o wiele szybsze.
Wymyślono więc następujący schemat bezpiecznego
przesyłania danych:
- A generuje klucz K, który używany będzie później przy
przesyłaniu danych algorytmem symetrycznym.
- A wysyła klucz K do B korzystając z jego klucza publicznego
- B odczytuje klucz K korzystając ze swojego klucza
prywatnego.
- Strony dalej komunikują się korzystając z szyfrowania
symetrycznego z użyciem klucza K
Możliwe są różne wariacje tej metody umożliwiające na przykład:
- Autentyfikację serwera/klienta
Można to zrealizować na etapie nawiązywania połączenia - właściwie
sytuacja jest tu taka, jakby używany był tylko algorytm
asymetryczny.
- Okresową wymianę kluczy
Strony mogą się umówić, że przykładowo co 15 minut niszczą i od
nowa generują klucze symetryczne. Może to być ważne przy
połączeniach trwających bardzo długo i takich, po których przesyła
się niewiele danych. Ktoś posiadający odpowiednio szybki komputer
i będący w stanie podsłuchać szyfrowaną transmisję mógłby wtedy
jednak dane odszyfrować.
Przykłady zastosowania opisywanej metody to:
- SSH (Secure Shell)- protokół bezpiecznego logowania się
do systemu zdalnego.
Zaletą SSH w porównaniu z logowaniem się przy pomocy
telneta lub rsh (oczywiście poza bezpieczeństwem)
jest fakt, że można wyeliminować podawanie hasła - do
autentyfikacji wystarczający jest klucz prywatny klienta.
- SSL (Secure Socket Layer) - protokół bezpiecznych połączeń
WWW, któremu poświęcona jest dalsza część tego dokumentu.
II Protokół SSL
1. Podstawy
Najkrócej mówiąc, protokół SSL jest praktycznym wykorzystaniem
algorytmów opisanych dotychczas dla potrzeb bezpiecznej
komunikacji w sieci Internet. W swej podstawowej wersji
zabezpiecza on protokół HTTP, jednak z użyciem dodatkowych
narzędzi można z jego pomocą obudować również usługi FTP, news i
poczty elektronicznej.
Ważnym problemem, który pojawił się przy
implementacji bezpiecznych połączeń sieci WWW była sprawa
autentyfikacji kluczy publicznych. To, że nie muszą one być tajne
nie oznacza wcale, że mogą być zupełnie nie zabezpieczone przed
atakami - powinna istnieć jakaś metoda zabezpieczania
integralności kluczy publicznych.
W większości rozwiązań z tym problemem poradzono
sobie wprowadzając pewne "zaufane" instytucje przechowujące klucze
publiczne. Przykładowo w systemie PGP istnieje w sieci centralna
baza kluczy publicznych, w której dostępne są klucze wielu znanych
osób. Również integralną częścią protokołu SSL jest mechanizm
obsługi certyfikatów
2. Certyfikaty
Certyfikat jest to zbiór danych jednoznacznie identyfikujących
pewną jednostkę (na przykład osobę, lub komputer) oraz pozwalający
stwierdzić, czy osoba, która się nim legitymuje jest rzeczywiście
tym, za kogo się podaje. Jest on potwierdzony przez zaufaną
organizację, zwaną w protokole SSL certificate authority
(CA). Certyfikat zawiera:
- Nazwę certyfikowanego obiektu
- Identyfikator obiektu
- Klucz publiczny obiektu
- Czas ważności
- Nazwę wystawcy certyfikatu
- Identyfikator wystawcy
- Podpis wystawcy
(To pole zawiera jednoznaczny skrót całego certyfikatu
zaszyfrowany przy pomocy klucza prywatnego wystawcy.)
Szczególnym przypadkiem jest certyfikat poświadczający tożsamość
CA - identyfikator wystawcy jest w nim równy identyfikatorowi
obiektu, a skrót certyfikatu jest szyfrowany kluczem publicznym
obiektu! Jest to logiczna konsekwencja przyjętego założenia, że CA
jest instytucją zaufaną i jej tożsamości nie trzeba sprawdzać (a
właściwie nie można, bo kto ją miałby potwierdzić?).
W ogólnym przypadku mamy tak zwany łańcuch
certyfikatów. Nie musimy (a nawet nie powinniśmy) bowiem dla
każdego obiektu w danym systemie wystawiać certyfikatu
potwierdzonego przez CA, gdyż spowodowałoby to przeciążenie tych
instytucji i niepotrzebny rozrost bazy danych. Możemy na własne
potrzeby ustanowić lokalny urząd certyfikacyjny który
będzie poświadczał lokalne certyfikaty, a sam będzie legitymował
się certyfikatem poświadczonym przez CA.
W takim przypadku przy autentyfikacji certyfikatu
możliwe są dwie sytuacje:
- Jeżeli możemy sobie na to pozwolić, to ustalamy, że wewnątrz
naszej sieci ufamy wszystkim certyfikatom potwierdzonym przez
lokalny CA - wtedy w zasadzie możemy zrezygnować z usług
zewnętrznej instytucji certyfikującej.
- Jeżeli jednak chcemy sprawdzić, czy instytucja
potwierdzająca certyfikat, który właśnie otrzymaliśmy jest
faktycznie tym, za kogo się podaje, zawsze możemy w analogiczny
sposób zweryfikować jej certyfikat. W ten sposób w końcu dojdziemy
do kogoś komu ufamy (w najgorszym razie będzie to któryś z
międzynarodowych CA - ale komuś ufać musimy :).
Problemem który pojawia się wraz z certyfikatami jest ich
unieważnianie. O ile bowiem łatwo jest stwierdzić, czy
certyfikat nie jest już za stary - zawiera on odpowiednie pole, to
może się okazać, że należy certyfikat unieważnić przed jego
terminem wygaśnięcia. Przykładowo, jeśli z pracy odchodzi
pracownik posiadający dostęp do ważnych danych firmy, to powinna
istnieć możliwość odebrania mu tych uprawnień niezależnie od
terminu ważności jego certyfikatu.
Rozwiązanie (choć nie idealne) tego problemu to
listy unieważnień (certificate revocation lists)
przechowywane we wszytkich serwerach wystawiających certyfikaty.
Ich działanie polega na tym, że klient przy sprawdzaniu
autentyczności dowolnego certyfikatu musi zgłosić się do jego
wystawcy i poprosić o sprawdzenie, czy przypadkiem nie został on
unieważniony przed czasem.
Nie jest to niestety rozwiązanie idealne, gdyż
generuje dodatkowy ruch w sieci i jest dość "sztuczne". Niestety
jak do tej pory nie wymyślono nic lepszego i często wręcz nie
stosuje się żadnych metod uniewazniania certyfikatów.
3. Protokół SSL
SSL jest protokołem typu klient-serwer pozwalającym na nawiązanie
bezpiecznego połączenia z użyciem certyfikatów. Jest on
zorientowany głównie na autentyfikację serwera (np. sklepu
internetowego do którego klient wysyła numer karty kredytowej i
chce mieć pewność co do odbiorcy), ale przewiduje również
możliwość autoryzacji klienta.
Schemat działania protokołu wygląda następująco
(jako K oznaczamy klienta, a jako S - serwer):
- K -> S ClientHello
Klient wysyła do serwera zgłoszenie zawierające m.in. obsługiwaną
wersję protokołu SSL, dozwolone sposoby szyfrowania i kompresji
danych oraz identyfikator sesji. Komunikat ten zawiera również
liczbę losową używaną potem przy generowaniu kluczy.
- K <- S ServerHello
Serwer odpowiada podobnym komunikatem w którym zwraca klientowi
wybrane parametry połączenia: wersję protokołu SSL, rodzaj
szyfrowania i kompresji, oraz podobną liczbę losową.
- K <- S Certificate
Serwer wysyła swój certyfikat pozwalając klientowi na sprawdzenie
swojej tożsamości (ten etap jest opcjonalny, ale w większości
przypadków występuje)
- K <- S ServerKeyExchange
Serwer wysyła informację o swoim kluczu publicznym. Rodzaj i
długośc tego klucza jest określony przez typ algorytmu przesłany w
poprzednim komunikacie.
- K <- S ServerHelloDone
Serwer zawiadamia, że klient może przejść do następnej fazy
zestawiania połączenia.
- K -> S ClientKeyExchange
Klient na podstawie ustalonych w poprzednich komunikatach dwóch
liczb losowych (swojej i serwera) generuje klucz sesji używany do
faktycznej wymiany danych. Następnie wysyła go serwerowi używając
jego klucza publicznego.
Uwaga: wygenerowany klucz jest kluczem algorytmu
symetrycznego (typowo DES)! Jest on jednak ustalony w
sposób bezpieczny i znany jest tylko komunikującym się stronom.
- K -> S ChangeCipherSpec
Klient zawiadamia, że serwer może przełączyć się na komunikację
szyfrowaną.
- K -> S Finished
... oraz że jest gotowy do odbierania danych zakodowanych.
- K <- S ChangeCipherSpec
Serwer zawiadamia, że wykonał polecenie - od tej pory wysyłał
będzie tylko zaszyfrowane informacje.
- K <- S Finished
... i od razu wypróbowuje mechanizm - ten komunikat jest już
wysyłany bezpiecznym kanałem!
Protokół SSL przewiduje również kontrolowane zakończenie
połączenia. Jest ważne, gdyż nie można dopuścić do sytuacji, w
której potencjalny intruz jest w stanie przerwać fizyczny kanał
komunikacyjny i tym samym zniekształcić treść przesyłanej
wiadomości.
Do kontrolowania zakończenia połączenia służy
komunikat ClosureAlert.
4. Autentyfikacja klienta
Jak widać na schemacie z poprzedniego punktu, w protokole SSL
domyślna sytuacja zakłada tylko autentyfikację serwera. Istnieją
jednak metody pozwalające na autentyfikację klienta. W tym celu
korzysta się z trzech dodatkowych komunikatów:
- K <- S CertificateRequest
Po przesłaniu swojego certyfikatu serwer zawiadamia, że chciałby
otrzymać certyfikat klienta
- K -> S Certificate
Po otrzymaniu komunikatu ServerHelloDone klient odsyła swój
certyfikat
- K -> S CertificateVerify
Klient musi potwierdzić, że faktycznie posiada klucz prywatny
odpowiadający wysłanemu certyfikatowi. W tym celu klient szyfruje
swoim kluczem prywatnym skrót wszystkich dotychczas ustalonych
danych o połączeniu i wysyła go korzystając z tego komunikatu.
5. Odtwarzanie poprzedniej sesji
Nawiązanie połączenia SSL jest procesem dość długotrwałym i
wymagającym skomplikowanych obliczeń. W przypadku wielu krótkich
połączeń pożądana byłaby możliwość kontynuowania połączenia bez
ponownej wymiany kluczy publicznych, ustalania klucza sesji itp.
(Podobna sytuacja ma miejsce w przypadku protokołu HTTP -
stosowane są tam tzw. połączenia trwałe - persistent
connections.
Protokół SSL przewiduje taką możliwość. Jeżeli w
komunikacie ClientHello klient poda SessionId równy
identyfikatorowi jednej z poprzednich sesji, to serwer przyjmie,
że klient chce kontynuować połączenie z użyciem poprzednio
uzywanego klucza.
Literatura:
- Stephen Thomas - "SSL and TLS Essentials", Wiley and Sons 2000
|