JAVA - bezpieczeństwo

Autor: Marcin Kasiński
24.04.2011 12:59:49 +0200

SSL

Protokół SSL (Secure Socket Layer) został w początkowej wersji opracowany przez firmę Netscape i stał się wkrótce standardem, powszechnie stosowanym w Internecie. Ostatnia, trzecia wersja protokołu (SSLv3) stała się podstawą do opracowania nieco ulepszonego i firmowanego przez IETF protokołu TLS (Transport Layer Security).

Przeznaczenie SSL

Podstawowymi zadaniem SSL jest zapewnienie bezpiecznego kanału dla protokołów wyższych warstw. Kanał taki, dzięki zastosowaniu kryptografii, jest zupełnie nieprzezroczysty dla osoby podsłuchującej łączność lub próbującej modyfikować jej przebieg.

Protokół SSL gwarantuje następujące funkcje:

Autentyczność stron

Obie strony komunikacji mają pewność, że są rzeczywiście tymi, za których się podają. Ma to znaczenie w przypadku ataków polegających na podszywaniu się za inny komputer. Za pomocą protokołu SSL ta możliwość została rozwiązana i nie tu już moziwości podszywania się za kogoś innego.

Poufność transmisji

Oznacza to ochronę przesyłanych danych przed podsłuchem przez ich zaszyfrowanie. Szyfrując wiadomość kluczem publicznym odbiorcy mamy pewność, że tylko on ją jest w stanie odczytać, ponieważ jest to możliwe tylko drugą para kluczy, w tym wypadku kluczem prywatnym odbiorcy. Dzieje się tak dlatego, że jak sama nazwa wskazuje klucz prywatny ma tylko i wyłącznie odbiorca i nikt inny bez tego klucza nie jest w stanie tej wiadomości odczytać.

Integralność danych

Oznacza to pewność, że przesłane dane nie zostały zmodyfikowane po drodze, czy to w wyniku awarii czy złośliwej ingerencji. Szyfrując wiadomość własnym kluczem prywatnym i wysyłając go, odbiorca ma pewność, że informacje w międzyczasie nie zostały zmienione. Dzieje się tak dlatego, że wiadomość zakodowaną kluczem prywatnym możemy odczytać tylko i wyłącznie jego kluczem publicznym. Jednym z podstawowych założeń SSL była otwartość i rozszerzalność protokołu, czyli brak przywiązania do jednego, konkretnego algorytmu szyfrującego. Zamiast tego protokół umożliwia stronom przedstawienie swoich propozycji obsługiwanych algorytmów i wybranie wspólnego, najbardziej odpowiedniego dla obu stron. Przykładowo, klient łączący się z serwerem po SSL może oznajmić mu, że może użyć algorytmów szyfrujących DES, 3DES oraz RC4. Jeśli serwer stwierdzi, że z zaproponowanej listy obsługuje wyłącznie RC4, to ten właśnie algorytm zostanie użyty do zabezpieczenia transmisji.

Kryptografia w SSL

Jak wiele innych protokołów tego rodzaju, SSL wykorzystuje dwa podstawowe rodzaje szyfrów, szyfry asymetryczne (z kluczem prywatnym i publicznym) oraz symetryczne (z jednym kluczem szyfrująco - deszyfrującym). Pierwsze z nich są wykorzystywane do uwierzytelnienia stron oraz bezpiecznej wymiany klucza symetrycznego, który z kolei służy do faktycznego szyfrowania strumienia danych. Powody, dla których tak się robi są dwa: po pierwsze, algorytmy z kluczem publicznym są znacznie wolniejsze od szyfrów symetrycznych, przez co nie nadają się do wydajnego kodowania danych przesyłanych w dużych strumieniach. Z drugiej jednak strony zastosowanie tylko i wyłącznie szyfru symetrycznego wymagałoby wcześniejszej wymiany klucza za pomocą jakiegoś innego kanału. Połączenie dwóch rodzin szyfrów rozwiązuje oba te problemy w sposób efektywny i elegancki.

Działanie protokołu

Typowa sesja SSL składa się z następujących kroków:

  • 1. Nawiązanie przez klienta połączenia do serwera (po zwykłym TCP).
  • 2. Wymiana informacji o obsługiwanych szyfrach, certyfikatów tożsamości i innych danych.
  • 3. Uzgodnienie wspólnego zbioru obsługiwanych algorytmów szyfrowania.
  • 4. Potwierdzenie tożsamości serwera przez klienta na podstawie otrzymanych informacji (opcjonalnie także potwierdzenie tożsamości klienta przez serwer).
  • 5. Jeśli serwer wymaga tego, to opcjonalnie potwierdzenie tożsamości klienta przez serwer.
  • 6. Wymiana kluczy sesyjnych (session keys), wygenerowanych w sposób losowy.
  • 7. Rozpoczęcie transmisji całkowicie szyfrowanej wygenerowanymi wcześniej kluczami.

W punktach 2, 3 i 4 wykorzystywany jest szyfr asymetryczny, wybrany ze wspólnej listy7. Po zakończeniu ostatniego (5) etapu kanał SSL staje się całkowicie przezroczysty dla tunelowanego wewnątrz protokołu wyższej warstwy. Do szyfrowania właściwych danych tunelowanych w SSL jest wykorzystywany szyfr symetryczny, jeden z uzgodnionych podczas początkowej wymiany. Klucz szyfrujący jest generowany losowo dla każdego połączenia.

Infrastruktura klucza publicznego (PKI)

Podstawą uwierzytelnienia w SSL są mechanizmy infrastruktury klucza publicznego (PKI), oparte o kryptografię asymetryczną. W modelu tym każdy węzeł posiada swój klucz prywatny, chroniony przed kradzieżą, oraz klucz publiczny, który jest wysyłany do klienta podczas nawiązywania połączenia. Z punktu widzenia klienta łączącego się z takim systemem nie jest to jednak wystarczające dla stwierdzenia autentyczności przedstawionego klucza publicznego ( w przypadku ataku typu man-in-the-middle klucz ten mógłby być podstawiony).

W modelu PKI najważniejszą rolę spełnia tutaj zaufana trzecia strona (trusted third party), czyli ktoś obdarzany zaufaniem przez obie strony połączenia. W praktyce może to być instytucja rządowa, firma posiadająca odpowiednią akredytację lub, w ramach jednej instytucji, wydzielona komórka organizacyjna. W terminologii PKI organy te są określane wspólną nazwą urzędów certyfikujących CA (Certifying Authority). Rolą CA jest w przypadku SSL uprzednie stwierdzenie tożsamości serwera oraz poświadczenie jej przez złożenie podpisu cyfrowego na kluczu publicznym zainteresowanego. Dowody przedstawiane przez tego ostatniego urzędowi zależą oczywiście od kontekstu. W przypadku właściciela sklepu internetowego, oferującego SSL i chcącego uzyskać certyfikat jednej z uznanych, światowych firm certyfikujących (VeriSign, Thawte) będzie to dokument poświadczający istnienie danej firmy (wypis z ewidencji gospodarczej), prawo do domeny sklepu (uzyskany od firmy rejestrującej domeny, np. NASK lub Network Solutions) itp. W przypadku CA działającego w obrębie jednej firmy może to być zaświadczenie z działu kadr lub wręcz ustna deklaracja przełożonego, w zależności od wielkości i polityki firmy.

Hierarchia CA

PKI jest systemem w ogromnym stopniu skalowalnym, gdyż pracuje równie dobrze w ramach jednej firmy, międzynarodowej korporacji oraz ogólnoświatowej sieci certyfikacji publicznej, stosowanej obecnie w Internecie. Taka złożoność nie byłaby możliwa gdyby PKI nie było systemem hierarchicznym, umożliwia ono bowiem delegację części uprawnień certyfikacyjnych do podmiotów niższego szczebla. Mówiąc obrazowo, urząd certyfikujący szczebla rządowego może podpisać klucz publiczny urzędu działającego w ramach określonej instytucji, dzięki czemu może ona tworzyć certyfikaty dla własnych pracowników bez angażowania organu nadrzędnego. Równocześnie, dzięki podpisowi złożonemu przez krajowego CA, certyfikaty wygenerowane przez tę instytucję będą mogły być weryfikowane tak samo skutecznie, jakby były one wygenerowane przez urząd wyższego szczebla.

Weryfikacja tożsamości

Jak przebiega sprawdzenie tożsamości serwera legitymującego się certyfikatem? Przede wszystkim, klient musi w tym celu posiadać klucz publiczny urzędu, który podpisał dany certyfikat albo urzędu wyższego szczebla. Jest to podstawowe założenie PKI i punkt, od którego zależy bezpieczeństwo całego systemu, jako że klucz CA potwierdza tożsamość wszystkich kolejnych ogniw łańcucha certyfikacji. Sama weryfikacja odbywa się w ten sposób, że klient po otrzymaniu od serwera jego certyfikatu sprawdza jaki urząd go podpisał. Następnie szuka w swojej wewnętrznej bazie certyfikatu tego urzędu. Jeśli go nie znajdzie, może spróbować poszukać go w bazie zewnętrznej ( do tego celu wykorzystuje się powszechnie katalogi LDAP ).

Zakres ochrony PKI

Autentyczność podpisu na kluczu publicznym nie jest jedyną cechą zapewnianą przez SSL. Sprawdzane są także daty wystawienia oraz utraty ważności certyfikatu (mógł on zostać wystawiony tylko na rok) oraz, opcjonalnie, czy nie był on anulowany przez ogłoszenie na publicznej liście unieważnionych certyfikatów (Certificate Revocation List). Faktyczne wykorzystanie licznych mechanizmów zapewnianych przez PKI zależy od implementacji oraz potrzeb użytkownika, określonych przez projektanta konkretnego wdrożenia.

JAVA SSL API

Zasadniczo API JAVA pozwalające na komunikacje TCP z wykorzystaniem połączenia szyfrowanego wiele się nie różni od takiego samego połączenia tylko nie szyfrowanego. Podstawową operacją, jaka tu należy wykonać przed rozpoczęciem ze strony serwera nasłuchiwanie , czy też ze strony klienta połączenia do serwera jest określenie po obu stronach parametrów związanych z szyfrowaną komunikacją. Te parametry, to położenie pliku z bazą certyfikatów oraz pliku z bazą zaufanych kluczy publicznych oraz dodatkowo hasła do oby tych plików.

Parametry takie ustawiamy poprzez zmienne systemowe JAVA albo programistycznie albo poprzez dodatkowe parametry wywołania. Programistycznie można tego dokonać np. przez poniższy kod:

System.setProperty("javax.net.ssl.keyStore","/mnt/hd3/keyStore");
System.setProperty("javax.net.ssl.keyStorePassword","haslo");
System.setProperty("javax.net.ssl.trustStore","/mnt/hd3/trustStore");
System.setProperty("javax.net.ssl.trustStorePassword","haslo");

Te same parametry ustawione w wywołaniu będą wyglądać następująco:


java -Djavax.net.ssl.keyStore=/mnt/hd3/keyStore 
	-Djavax.net.ssl.keyStorePassword=haslo 
	-Djavax.net.ssl.trustStore=/mnt/hd3/trustStore 
	-Djavax.net.ssl.trustStorePassword=haslo nazwa_klasy_do_uruchomienia

Dalej same rozpoczęcie komunikacji po stronie klienta może mieć postać:


SocketFactory ssf = SSLSocketFactory.getDefault();
Socket sockettoserver = ssf.createSocket(listener.host,listener.port);

Po stronie serwera natomiast rozpoczęcie nasłuchiwania może wyglądać następująco:


ServerSocketFactory ssf = SSLServerSocketFactory.getDefault();
ServerSocket ssoc = ssf.createServerSocket(port);

Przykład

Poniżej opiszę przykład ustanowienia bezpiecznego połączenia pomiędzy klientem, a serwerem z wykorzystaniem standardowego narzędzia keytool. Pierwszym elementem jakim się zajmiemy jest przygotowanie odpowiednich bazy certyfikatów po stronie klienta i serwera. Nasttępnie powinniśmy dla klienta i serwera w ich bazie umieścić odpoweiednie pary kluczy. Po wygenerowaniu tych kluczy certyfikatu publiczne danej strony komunikacji powinniśmy umieścić w bazie kluczy drugiej strony. Oznacza to, że certyfikat publiczny serwera powinien być umiesczony w bazie kluczy klienta i odwrotnie.

Poniżej zostaną opisane konkretne kroki do wykonania abyć użyskać oczekiwany efekt.

Wygenerowanie pary kluczy dla klienta i serwera.

keytool -genkey -alias "client" -keystore client.jks -keyalg RSA -sigalg SHA1withRSA
keytool -genkey -alias "it zone" -keystore itzone.jks -keyalg RSA -sigalg SHA1withRSA

Wygenerowanie zapytanie o podpisanie certyfikatu (CSR) dla klienta i serwera

keytool -certreq -alias "client" -keystore client.jks -file server.csr
keytool -certreq -alias "it zone" -keystore itzone.jks -file client.csr

Podpisanie certyfikatu przez CA

openssl x509 -CA caroot.cer -CAkey cakey.pem -CAserial serial.txt -req \
-in server.csr -out server.cer -days 365

openssl x509 -CA caroot.cer -CAkey cakey.pem -CAserial serial.txt -req \
-in client.csr -out client.cer -days 365

Import podpisanych certyfikatów

keytool -import -alias "client" -file client.cer -keystore client.jks
keytool -import -alias "it zone" -file server.cer -keystore itzone.jks

Import głównego certyfikatu publicznego CA

keytool -import -alias ca -file ca.cer -keystore client.jks
keytool -import -alias ca -file ca.cer -keystore itzone.jks

Powyższe czynności są rekomendowane dla środowisk PRD. W przypadku środowisk developerskich oraz testowych można uprościć konfiguracje poprzez wygenerowanie kluczy samopodpisanych. W takiej sytuacji nie potrzebujemy CA, ponieważ kluczpodpisujemysamemu sobie. Wygenerowanie samopodpisanego certyfikatu odbywa się dla klienta i serwera poprzez poniższe komendy.

keytool -genkey -keyalg RSA -alias "client" -keystore cient.jks -validity 360 -keysize 2048
keytool -genkey -keyalg RSA -alias "it zone" -keystore itzone.jks -validity 360 -keysize 2048

Teraz możemy obejrzeć zawartość bazy certyfikatów klienta i serwera.

keytool -v -list -keystore cient.jks
keytool -v -list -keystore itzone.jks

powrót
Zachęcam do przedstawienia swoich uwag i opinii w polu komentarzy.

Komentarze

Dodaj Komentarz