Ćwiczenie 9 - Zaawansowane metody programowania w sieci komputerowej



Podobne dokumenty
JAVA I SIECI. MATERIAŁY:

Łukasz Przywarty Wrocław, r. Grupa: WT/N 11:15-14:00. Sprawozdanie z zajęć laboratoryjnych: OpenSSL - API

Bezpieczne uruchamianie apletów wg

Przykłady interfejsu TCP i UDP w Javie

Programowanie w języku Java

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Wykład 4. Metody uwierzytelniania - Bezpieczeństwo (3) wg The Java EE 5 Tutorial Autor: Zofia Kruczkiewicz

Programowanie rozproszone w języku Java

Aplikacja wielowątkowa prosty komunikator

Wprowadzenie do PKI. 1. Wstęp. 2. Kryptografia symetryczna. 3. Kryptografia asymetryczna

Język JAVA podstawy. Wykład 6, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Kryptografia. z elementami kryptografii kwantowej. Ryszard Tanaś Wykład 11

Aplikacje RMI. Budowa aplikacji rozproszonych. Część 2.

Laboratorium nr 5 Podpis elektroniczny i certyfikaty

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Katedra Architektury Systemów Komputerowych Wydział Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej

Java jako język programowania

Java programowanie w sieci. java.net RMI

Java, bazy danych i SSL

Podstawy i języki programowania

Aplikacja wielow tkowa prosty komunikator

Wywoływanie metod zdalnych

Serwer SSH. Wprowadzenie do serwera SSH Instalacja i konfiguracja Zarządzanie kluczami

Programy typu klient serwer. Programowanie w środowisku rozproszonym. Wykład 5.

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura

Dokumentacja do API Javy.

Programowanie współbieżne i rozproszone

Wywoływanie metod zdalnych

Kurs programowania. Wykład 10. Wojciech Macyna. 05 maja 2016

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Płace Optivum. Jakie czynności musi wykonać pracownik, aby otrzymywać drogą elektroniczną paski z list płac?

Hosting WWW Bezpieczeństwo hostingu WWW. Dr Michał Tanaś (

Systemy internetowe. Wykład 5 Architektura WWW. West Pomeranian University of Technology, Szczecin; Faculty of Computer Science

Remote Method Invocation 17 listopada Dariusz Wawrzyniak (IIPP) 1

Podejście obiektowe do budowy systemów rozproszonych

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Wybrane działy Informatyki Stosowanej

Przykłady ataków. Błąd dotyczy np. forów dyskusyjnych z możliwością umieszczania plików grafcznych. Pozwala to na wykonanie dowolnego żądania HTTP.

Tworzenie i wykorzystanie usług

SSL (Secure Socket Layer)

Platformy Programistyczne Zagadnienia sieciowe i wątki

KAMELEON.CRT OPIS. Funkcjonalność szyfrowanie bazy danych. Wtyczka kryptograficzna do KAMELEON.ERP. Wymagania : KAMELEON.ERP wersja

Aplikacje RMI

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

KLASY, INTERFEJSY, ITP

Podstawy Secure Sockets Layer

Zdalne wywołanie metod - koncepcja. Oprogramowanie systemów równoległych i rozproszonych Wykład 7. Rodzaje obiektów. Odniesienie do obiektu

Komunikacja z użyciem gniazd aplikacje klient-serwer

Remote Method Invocation 17 listopada 2010

ZiMSK. Konsola, TELNET, SSH 1

Oprogramowanie systemów równoległych i rozproszonych Wykład 7

PGP - Pretty Good Privacy. Użycie certyfikatów niekwalifikowanych w programie PGP

Wieloplatformowe aplikacje sieciowe. dr inż. Juliusz Mikoda mgr inż. Anna Wawszczak

MAMP: Można to pobrać i zainstalować z XAMPP: Można go pobrać i zainstalować z

Zadanie 1: Protokół ślepych podpisów cyfrowych w oparciu o algorytm RSA

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Portal SRG BFG. Instrukcja korzystania z Portalu SRG BFG

Instrukcja obsługi certyfikatów w programie pocztowym MS Outlook Express 5.x/6.x

Przewodnik użytkownika

Portal SRG BFG Instrukcja korzystania z Portalu SRG BFG

Programowanie obiektowe

Zamiana porcji informacji w taki sposób, iż jest ona niemożliwa do odczytania dla osoby postronnej. Tak zmienione dane nazywamy zaszyfrowanymi.

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

1. Co można powiedzieć o poniższym kodzie? public interface I { void m1() {}; static public void m2() {}; void abstract m3();

Ćwiczenie 1. Przygotowanie środowiska JAVA

Java wybrane technologie

systemów intra- i internetowych Platformy softwarowe dla rozwoju Architektura Internetu (2) Plan prezentacji: Architektura Internetu (1)

JAX-RS czyli REST w Javie. Adam Kędziora

Bezpieczeństwo Systemów Komputerowych. Wirtualne Sieci Prywatne (VPN)

INSTRUKCJA INSTALACJI I OBSŁUGI GPG4Win

Instrukcja generowania żądania CSR SOW WERSJA 1.6

Instrukcja generowania certyfikatu PFRON i podpisywania dokumentów aplikacji SODiR w technologii JS/PKCS 12

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Protokoły zdalnego logowania Telnet i SSH

Zaawansowane aplikacje internetowe - laboratorium Architektura CORBA.

Bezpieczeństwo systemów informatycznych

Podejście obiektowe do budowy systemów rozproszonych

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

Zdalne logowanie do serwerów

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Aplikacje w Javie- wykład 11 Wątki-podstawy

Wykład 4. komputerowych Protokoły SSL i TLS główne slajdy. 26 października Igor T. Podolak Instytut Informatyki Uniwersytet Jagielloński

Programowanie obiektowe zastosowanie języka Java SE

DESlock+ szybki start

Remote Method Invocation 17 listopada rozproszonych. Dariusz Wawrzyniak (IIPP) 1

Dzisiejszy wykład. Wzorce projektowe. Visitor Client-Server Factory Singleton

Multimedia JAVA. Historia

Wykład 8: Obsługa Wyjątków

Wykład 7: Pakiety i Interfejsy

Aplikacje RMI Lab4

PuTTY. Systemy Operacyjne zaawansowane uŝytkowanie pakietu PuTTY, WinSCP. Inne interesujące programy pakietu PuTTY. Kryptografia symetryczna

Podstawy programowania obiektowego

Windows Serwer 2008 R2. Moduł 5. Zarządzanie plikami

Systemy Operacyjne zaawansowane uŝytkowanie pakietu PuTTY, WinSCP. Marcin Pilarski

Czym jest kryptografia?

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

Transkrypt:

Ćwiczenie 9 - Zaawansowane metody programowania w sieci komputerowej Bezpieczne gniazda Poufna komunikacja przez otwarte medium, takie jak Internet, która ma uniemożliwiać podsłuch, bezwzględnie wymaga szyfrowania danych. Większość algorytmów szyfrowania, które mogą być realizowane przez komputery, opiera się na pojęciu klucza - rodzaju hasła, które nie jest ograniczone do tekstu. Komunikat pisany jawnym tekstem jest łączony z bitami klucza według pewnego algorytmu matematycznego, w wyniku czego otrzymuje się tekst zaszyfrowany. Używanie kluczy o większej liczbie bitów wykładniczo utrudnia odszyfrowanie komunikatu przez odgadywanie kluczy metodą brutalnej siły. W tradycyjnym szyfrowaniu kluczem tajnym (czyli szyfrowaniu symetrycznym) ten sam klucz służy do szyfrowania i deszyfrowania danych. Zarówno nadawca, jak i odbiorca muszą mieć jeden klucz. Przypuśćmy, że Anna chce wysłać Markowi tajną wiadomość. Najpierw wysyła Markowi klucz, który posłuży do przesłania sekretu. Klucz nie może jednak być zaszyfrowany, ponieważ Marek nie zna jeszcze klucza, więc Anna wysyła go w niezaszyfrowanej postaci. Załóżmy teraz, że Jan podsłuchuje połączenie między Anną i Markiem. Uzyska on klucz w tym samym momencie co Marek. Od tej chwili będzie mógł odczytywać wszystko, co Anna i Marek sobie przekazują. W szyfrowaniu kluczem publicznym (czyli szyfrowaniu asymetrycznym) do szyfrowania i deszyfrowania danych używa się innych kluczy. Jeden, nazywany kluczem publicznym, służy do szyfrowania danych. Ten klucz można dać każdemu. Drugi, nazywany kluczem prywatnym, służy do deszyfrowania danych. Musi być utrzymywany w tajemnicy, ale wystarczy, że będzie go miał tylko jeden z korespondentów. Jeśli Anna chce wysłać wiadomość do Marka, prosi go o klucz publiczny. Marek wysyła Annie klucz przez niezaszyfrowane połączenie. Anna szyfruje swoją wiadomość kluczem publicznym Marka i wysyła ją. Jeśli Jan podsłuchiwał, kiedy Marek przesyłał Annie klucz, to przechwycił klucz publiczny Marka. Nie pozwoli mu to jednak na rozszyfrowanie wiadomości przesłanej przez Annę, bo do tego niezbędny jest klucz prywatny Marka. Wiadomość jest bezpieczna nawet wtedy, gdy klucz publiczny zostanie przechwycony. Szyfrowanie asymetryczne może być także używane do uwierzytelniania i sprawdzania integralności komunikatów. Anna może na przykład zaszyfrować wiadomość swoim kluczem prywatnym. Kiedy Marek otrzyma wiadomość, spróbuje 1

rozszyfrować ją za pomocą klucza publicznego Anny. Jeśli to się uda, Marek będzie wiedział, że wiadomość przyszła od Anny - nikt inny nie mógłby utworzyć wiadomości, którą dałoby się poprawnie rozszyfrować za pomocą klucza publicznego Anny. Marek będzie również wiedział, że wiadomość nie została zmodyfikowana po drodze, albo celowo (przez Jana), albo przypadkowo (przez błędne oprogramowanie albo szum sieciowy), ponieważ każda zmiana uniemożliwiłaby jej rozszyfrowanie. Anna mogłaby także zaszyfrować wiadomość dwukrotnie, raz swoim kluczem prywatnym, a raz kluczem publicznym Marka, zyskując za jednym zamachem poufność, uwierzytelnienie i ochronę integralności. W praktyce szyfrowanie kluczem publicznym dużo bardziej obciąża procesor i jest znacznie wolniejsze niż szyfrowanie kluczem tajnym. Zamiast więc szyfrować całą komunikację za pomocą klucza publicznego Marka, Anna szyfruje tylko tradycyjny tajny klucz i przesyła go Markowi. Marek rozszyfrowuje go za pomocą swojego klucza prywatnego. Teraz Anna i Marek znają tajny klucz, a Jan nie. Dzięki temu Anna i Marek mogą skorzystać z szybszego szyfrowania kluczem tajnym, a Jan nie będzie mógł ich podsłuchać. Jan może jednak zaatakować ten protokół w inny sposób. (Bardzo ważne: atakowany jest protokół wysyłania i odbierania wiadomości, a nie same algorytmy szyfrujące. Atak ten nie wymaga złamania algorytmu szyfrującego i jest zupełnie niezależny od długości klucza). Jan nie tylko może odczytać klucz publiczny Marka w drodze do Anny, ale może też zastąpić go swoim własnym! Kiedy Anna będzie myślała, że szyfruje wiadomość kluczem publicznym Marka, w rzeczywistości będzie szyfrowała go kluczem Jana. Kiedy wyśle wiadomość, Jan przechwyci ją, rozszyfruje swoim kluczem prywatnym, zaszyfruje go kluczem publicznym Marka i prześle dalej do Marka. Nazywamy to atakiem typu człowiek w środku (ang. man-in-the-mid-dle). Jeśli Anna i Marek byliby zdani tylko na siebie, nie mogliby w prosty sposób się zabezpieczyć przed takim atakiem. Najpraktyczniejsze rozwiązanie polega na tym, że Marek i Anna przechowują i weryfikują swoje klucze publiczne w zaufanym, niezależnym urzędzie certyfikacyjnym. Zamiast przesyłać sobie klucze publiczne, pobierają je z urzędu certyfikacyjnego. Nadal nie jest to rozwiązanie idealne = Jan może wkraść się między Marka i urząd certfikacyjny, Annę i urząd certyfikacyjny oraz Annę i Marka - ale utrudnia zadanie Janowi. Jak widać na tym przykładzie, teoria i praktyka szyfrowania oraz uwierzytelniania -zarówno algorytmy, jak i protokoły - to trudna dziedzina, usłana polami 2

minowymi, na których poległ niejeden kryptograf-amator. Dużo łatwiej jest opracować zły niż dobry algorytm lub protokół szyfrujący, w dodatku nie zawsze wiadomo, które algorytmy i protokoły są dobre, a które nie. Żeby używać mocnego szyfrowania w swoich sieciowych programach Javy należy skorzystać z Java Secure Socket Extension (JSSE). JSSE to standardowe rozszerzenie Javy 1.2 i nowszych wersji, które wyręcza cię w szczegółach negocjowania algorytmów, wymiany kluczy, uwierzytelniania korespondentów i szyfrowania danych. JSSE pozwala na tworzenie gniazd klientów i serwerów, które niewidocznie obsługują negocjacje i szyfrowanie wymagane do bezpiecznej komunikacji. Ty musisz tylko wysłać swoje dane przez te same strumienie i gniazda, które znasz z poprzednich rozdziałów. Java Secure Socket Extension dzieli się na cztery pakiety: javax.net.ssl Abstrakcyjne klasy, które definiują programowy interfejs Javy do bezpiecznej komunikacji sieciowej. javax.net Abstrakcyjne klasy fabryk gniazd, używane zamiast konstruktorów do tworzenia bezpiecznych gniazd. javax.security.cert Minimalny zbiór klas do obsługi certyfikatów z kluczem publicznym, wymagany przez SSL w Javie l.1 (w Javie l.2 i późniejszych wersjach należy zamiast tego użyć pakietu java.security.cert). com.suń.net.ssl Konkretne klasy, które realizują algorytmy i protokoły szyfrujące w implementacji odniesienia JSSE opracowanej przez Suna. Z technicznego punktu widzenia nie są one częścią standardu JSSE. Inni implementatorzy mogą zastąpić ten pakiet swoim własnym, na przykład takim, który korzysta z rodzimego kodu danej platformy w celu przyspieszenia generacji kluczy i szyfrowania. Żaden z tych pakietów nie stanowi standardowej części JDK. Zanim będziesz 3

mógł skorzystać z zawartych w nich klas, będziesz musiał pobrać JSSE (wersję krajową lub międzynarodową) pod adresem http://fava.sun.com/products/jsse - jak zwykle, ten adres może się zmienić. W przyszłości interfejs ten mogą zrealizować także firmy trzecie. Implementacja odniesienia Suną jest rozpowszechniana jako plik zip, który możesz rozpakować i umieścić w dowolnym katalogu. W podkatalogu lib tego pliku znajdziesz trzy archiwa JAR: jcert.jar, jnet.jar i jsse.jar. Musisz umieścić je na swojej ścieżce klas. W Javie 1.2 i nowszych wersjach wystarczy przenieść je do katalogu jre/lib/ext. Natomiast w Javie 1.1 będziesz musiał dopisać do swojej zmiennej środowiskowej CLASSPATH ścieżkę do wszystkich archiwów. Następnie musisz zarejestrować dostawcę usług kryptograficznych, edytując plik jre/lib/extlsecurity/java.secuńty. Otwórz ten plik w edytorze tekstów i poszukaj linii podobnej do poniższej: security.provider.1=sun.security.provider.sun security.provider.2=com.sun.rsajca.provider W twoim pliku może się znajdować więcej albo mniej takich dostawców. Dodaj jeszcze jednego, wpisując następującą linię: security.provider.3=com.sun.net.ssl.internal.ssl.provider Być może będziesz musiał zmienić liczbę 3 na 2,4,5 lub inną kolejną liczbę w twojej sekwencji dostawców usług bezpieczeństwa. Jeśli zainstalujesz implementację JSSE napisaną przez firmę trzecią, dołączysz następną podobną linię z nazwą klasy wziętą z dokumentacji twojej implementacji JSSE. UWAGA Jeśli używasz wielu kopii JRE, będziesz musiał powtórzyć tę procedurę dla każdej kopii. Z niezrozumiałych dla mnie powodów Sun zainstalował oddzielne kopie JRE 1.3 w moim systemie plików, jedną na potrzeby kompilacji, a drugą na potrzeby uruchamiania programów. Musiałem dokonać tych zmian w obu kopiach, aby nakłonić programy JSSE do działania. 4

Jeśli nie zrobisz tego poprawnie, zobaczysz wyjątki w rodzaju java.net.socket- Exception: SSL implementation not available, kiedy spróbujesz uruchomić programy używające JSSE. Zamiast edytować plik java.security, możesz dodać poniższą linię do klas używających implementacji JSSE Suna: java.security.security.addprovider(new com.sun.net.ssl.internal.ssl. Może to być przydatne, jeśli piszesz oprogramowanie przeznaczone dla kogoś innego i nie chcesz prosić go o modyfikowanie pliku java.security. 2. Tworzenie bezpiecznych gniazd klienta Jeśli nie interesują cię szczegóły, używanie zaszyfrowanych gniazd SSL w celu porozumienia się z istniejącym zabezpieczonym serwerem jest bardzo proste. Zamiast tworzyć obiekt java.net.socket za pomocą konstruktora, uzyskujesz gniazdo z klasy javax.net.ssl.sslsocketfactory, używając jej metody create-socket().sslsocketfactory to klasa abstrakcyjna, która nie odbiega od typowego wzoru abstrakcyjnej fabryki obiektów: public abstract class SSLSocketFactory extends SocketFactory Poniższy przykład to nieskomplikowany program, który łączy się z zabezpieczonym serwerem HTTP, wysyła proste żądanie GET i wyświetla odpowiedź. Przykład 1. Klient HTTPS import java.net.*; import java.io.*; import java.security.*; import javax.net.ssl.*; public class HTTPSClient { public static void main(string[] args) { if (args.length == 0) { System.out.println( Użycie: java HTPSClient host ); return; 5

int port = 443; // domyślny port https String host = args[0]; try { Security.addProvider(new com.sun.net.ssl.internal.ssl. Provider()); SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket socket = (SSLSocket) factory.createsocket(host, port); Writer out = new OutputStreamWriter (socket.getoutputstream ()); // https wymaga pełnego adresu URL w linii GET out.write( GET http:// + host + / HTTP/1. l\r\n ); out.write( \r\n ); out.flush(); // czytamy odpowiedź BufferedReader in = new BufferedReader( new InputStreamReader(socket.getlnputStream())); int c; while ((c = in.read())!= -1) { System.out.write(c); out.close(); in.close(); socket.close(); catch (IOException e) { System.err.println(e); Kiedy uruchomisz ten program, zapewne zauważysz, że reaguje ze znacznym opóźnieniem. Generowanie i wymiana kluczy publicznych stanowi znaczne obciążenie dla procesora i sieci. Jeśli nawet masz szybkie połączenie sieciowe, nawiązywanie połączenia może trwać 10 sekund, a nawet dłużej. Nie powinieneś więc udostępniać przez HTTPS wszystkich swoich danych, a tylko te, których prywat- 6

ność naprawdę trzeba chronić. 3. Tworzenie bezpiecznych gniazd serwera Bezpieczne gniazda klientów to tylko połowa równania. Drugą są gniazda serwerów z obsługą SSL. Są to instancje klasy javax.net.sslserversocket: public abstract class SSLServerSocket extends ServerSocket Podobnie jak w przypadku SSLSocket, wszystkie konstruktory tej klasy są chronione. Wszystkie instancje SSLServerSocket są tworzone przez abstrakcyjną klasę fabryczną, javax.net.sslserversocketfactory: public abstract class SSLServerSocketFactory extends ServerSocketFactory Tak jak w przypadku SSLSocketFactory, instancja klasy SSLServerSocket- Factory jest zwracana przez statyczną metodę SSLServerSocketFactory.getDefault(): public static SSLServerSocketFactory.getDefault() Tak jak SSLSocketFactory, SSLServerSocketFactory ma trzy przedefiniowane metody createserversocket(), zwracające instancje klasy SSL- ServerSocket, których działanie łatwo zrozumieć przez analogię z konstruktorami klasy java.net.serversocket: public abstract ServerSocket createserversocket(int port) throws IOException public abstract ServerSocket createserversocket(int port, int queuelength) throws IOException public abstract ServerSocket createserversocket(int port, int ąueuelength, InetAddress interface) throws IOException Jeśli to wystarczyłoby do utworzenia zabezpieczonych gniazd serwerów, wówczas byłyby one nieskomplikowane i łatwe w użyciu. Niestety, potrzeba czegoś więcej. Fabryka zwracana przez metodę SSLServerSocketFactory.get- 7

Default() obsługuje tylko uwierzytelnianie serwera. Nie obsługuje szyfrowania. Aby połączenie było szyfrowane, bezpieczne gniazda serwerów muszą być odpowiednio zainicjowane i skonfigurowane. Szczegóły tej operacji zależą od implementacji. W implementacji odniesienia opracowanej przez Suną za tworzenie w pełni skonfigurowanych i zainicjowanych gniazd serwerów odpowiedzialny jest obiekt com.sun.net.ssl.sslcontext. W różnych implementacjach JSSE proces przebiega odmiennie, ale w celu utworzenia zabezpieczonego gniazda w implementacji odniesienia, będziesz musiał: wygenerować klucze publiczne i certyfikaty za pomocą programu keytool, zapłacić za uwierzytelnianie twoich certyfikatów przez zaufaną stronę trzecią, na przykład Yerisign, utworzyć SSLContext dla używanego algorytmu, utworzyć TrustManagerFactory jako źródło danych certyfikacyjnych, których będziesz używać, utworzyć obiekt KeyS tore jako bazę danych z kluczami i certyfikatami (w implementacji Suna domyślnie jest to JKS), wypełnić KeyStore kluczami i certyfikatami, na przykład ładując je z pliku przy użyciu hasła, którym są zaszyfrowane, zainicjować KeyManagerFactory za pomocą obiektu KeyStore i jego hasła, zainicjować kontekst za pomocą odpowiednich menedżerów kluczy z Key- ManagerFactory, menedżerów zaufania z TrustManagerFactory i źródła danych losowych (ostatnie dwa parametry mogą być puste, jeśli chcesz przyjąć wartości domyślne). Poniższy przykład przedstawia tę procedurę w programie SecureOrderTaker, który przyjmuje zamówienia i wyświetla je na System.out. Oczywiście, w prawdziwej aplikacji zrobiłbyś z tymi zamówieniami coś bardziej interesującego. Przykład 2. SecureOrderTaker 8

import java.net.*; import java.io.*; import java.util.*; import java. security.*; import javax.net.ssl.*; import javax.net.*; import com.sun.net.ssl.*; public class SecureOrderTaker ( public finał static int DEFAULT_PORT = 7000; public finał static String algorithm = SSLv2 ; public static void main (String [] args) { int port = DEFAULT_PORT; if (args.length > 0) { try { port = Integer.parselnt(args [0]); if (port <= 0 port >= 65536) { System.out.println ( Port musi należeć do zakresu 0-65535 ); return; catch (NumberFormatException e) { try { SSLContext context = SSLContext.getlnstance( SSL ); // Implementacja odniesienia obsługuje tylko klucze X.509 KeyManagerFactory kmf = KeyManagerFactory.getlnstance( SunX509 ); // Domyślny rodzaj magazynu kluczy Suna KeyStore ks = KeyStore.getInstance( JKS ); // Ze względów bezpieczeństwa, każdy magazyn kluczy jest szyfrowany // za pomocą hasła, które należy podać, zanim załadujemy magazyn // z dysku. Hasło jest przechowywane w tablicy char[], aby można // było je szybko usunąć z pamięci, zamiast czekać na źbieracza // odpadków". Oczywiście, użycie znakowego literału pozbawia // to rozwiązanie jego zalet. 9

char[] password = 2andnotafnord.toCharArray(); ks.loadfnew FilelnputStream ( jnp2e19.keys ), password); kmf.init(ks, password); // context.init (kmf.getkeymanagers(), null, null); SSLServerSocketFactory factory = context.getserversocketfactory(); SSLServerSocket server = (SSLServerSocket) factory.createserversocket (port); // Zakończyliśmy konfigurację i możemy skupić się // na rzeczywistej komunikacji try { while (true) { // To gniazdo będzie zabezpieczone, // chociaż w kodzie tego nie widać. Socket connection = server.accept(); InputStream in = connection.getinputstream (); int c; while ((c = in.read(()!= -1) { System.out.write (c)); connection.close(); // end while // end try catch (IOException e) { System.err.println(e); // end catch // end try catch (IOException e) { e.printstacktrace(); // end catch catch (KeyManagementException e) { e.printstacktrace(); // end catch 10

catch (KeyStoreException e) { e.printstacktrace(); // end catch catch (NoSuchAlgorithmException e) { e.printstacktrace(); // end catch catch (java.security.cert.certificateexception e) { e.printstacktrace(); // end catch catch (UnrecoverableKeyException e) { e.printstacktrace (); // end catch // end main // end SecureOrderTaker 11