RSA w PHP: chronimy nasze dane przy użyciu kryptografii asymetrycznej

Podobne dokumenty
Podstawy technologii WWW

Funkcje i instrukcje języka JavaScript

Podstawy JavaScript ćwiczenia

Baza danych do przechowywania użytkowników

Aplikacje WWW - laboratorium

Specyfikacja instalacji usługi SMS Premium w Przelewy24.pl

Wprowadzenie do Internetu Zajęcia 5

Dokumentacja smsapi wersja 1.4

Przewodnik użytkownika

Bezpieczeństwo w sieci I. a raczej: zabezpieczenia wiarygodnosć, uwierzytelnianie itp.

Aplikacje internetowe - laboratorium

Laboratorium 1 Wprowadzenie do PHP

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

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

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

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

Laboratorium nr 5 Podpis elektroniczny i certyfikaty

Przykładowa integracja systemu Transferuj.pl

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

2.1. System kryptograficzny symetryczny (z kluczem tajnym) 2.2. System kryptograficzny asymetryczny (z kluczem publicznym)

Rejestracja i Logowania - PHP/MySQL

Laboratorium nr 3 Podpis elektroniczny i certyfikaty

Przykładowa integracja systemu tpay.com KIP S.A. ul. Św. Marcin 73/ Poznań.

Zaawansowane aplikacje internetowe

WSIZ Copernicus we Wrocławiu

MVC w praktyce tworzymy system artykułów. cz. 2

14. POZOSTAŁE CIEKAWE FUNKCJE

Wykład 03 JavaScript. Michał Drabik

Zajęcia 4 - Wprowadzenie do Javascript

Dane - pobieranie, przekazywanie i przechowywanie. dr Beata Kuźmińska-Sołśnia

Komunikator internetowy w C#

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

Dokumentacja Skryptu Mapy ver.1.1

Zastosowanie teorii liczb w kryptografii na przykładzie szyfru RSA

Bezpieczeństwo usług oraz informacje o certyfikatach

Technologia Internetowa w organizacji giełdy przemysłowej

Authenticated Encryption

Wprowadzenie do Doctrine ORM

PHP: bloki kodu, tablice, obiekty i formularze

e-awizo SYSTEM POTWIERDZANIA DORĘCZEŃ POCZTY ELEKTRONICZNEJ

Internetowe bazy danych

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

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

Aplikacje webowe w obliczu ataków internetowych na przykładzie CodeIgniter Framework

Instrukcja dla użytkowników Windows Vista Certyfikat Certum Basic ID

Certyfikat Certum Basic ID. Instrukcja dla użytkowników Windows Vista. wersja 1.3 UNIZETO TECHNOLOGIES SA

Referat z przedmiotu Technologie Internetowe SPIS TREŚCI

Dokumentacja interfejsu HTTPD. Platforma BSMS.PL Instrukcja podłączenia po przez http

Dokumentacja techniczna - PBL

INSTRUKCJA AKTYWACJI I INSTALACJI CERTYFIKATU ID

Laboratorium 6 Tworzenie bloga w Zend Framework

2 Kryptografia: algorytmy symetryczne

Technologie informacyjne lab. 4

Integracja frameworku Wicket z serwisem Platnosci.pl.

Szczegółowa specyfikacja funkcjonalności zamawianego oprogramowania.

Kontrola sesji w PHP HTTP jest protokołem bezstanowym (ang. stateless) nie utrzymuje stanu między dwoma transakcjami. Kontrola sesji służy do

Podstawy Secure Sockets Layer

API transakcyjne BitMarket.pl

Tworzenie stron internetowych z wykorzystaniem HTM5, JavaScript, CSS3 i jquery. Łukasz Bartczuk

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

Technologie Internetowe Raport z wykonanego projektu Temat: Internetowy sklep elektroniczny

Zdarzenia Zdarzenia onload i onunload

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

Podstawy systemów kryptograficznych z kluczem jawnym RSA

JQuery. $('#pierwszy').css('color','red').hide('slow').show(3000); $(document).ready(function() { //... tutaj nasze skrypty jquery //...

Systemy internetowe. Wykład 3 PHP. West Pomeranian University of Technology, Szczecin; Faculty of Computer Science

Spis treści. Wstęp 5 Rozdział 1. Praca z AJAX-em 9. Rozdział 2. Współpraca ze skryptami PHP 55. Rozdział 3. Obsługa formularzy 81

ZPKSoft WDoradca. 1. Wstęp 2. Architektura 3. Instalacja 4. Konfiguracja 5. Jak to działa 6. Licencja

Aplikacje internetowe

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

Szablon główny (plik guestbook.php) będzie miał postać:

Strategia gospodarki elektronicznej

Bezpieczna poczta i PGP

Szyfrowanie RSA (Podróż do krainy kryptografii)

Tworzenie witryn internetowych PHP/Java. (mgr inż. Marek Downar)

Aplikacje WWW - laboratorium

Jednym z najważniejszych zagadnień, z którym może się zetknąć twórca

WorkshopIT Komputer narzędziem w rękach prawnika

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

Komunikacja między klientem, a skryptem PHP, oraz operacje na plikach

RSA. R.L.Rivest A. Shamir L. Adleman. Twórcy algorytmu RSA

Podstawy technologii WWW

Baza danych sql. 1. Wprowadzenie. 2. Repozytaria generyczne

Bazy Danych i Usługi Sieciowe

Programowanie w Sieci Internet Python - c. d. Kraków, 28 listopada 2014 r. mgr Piotr Rytko Wydział Matematyki i Informatyki

SSL (Secure Socket Layer)

Aplikacje WWW - laboratorium

Publikowanie strony WWW

Personal Home Page PHP: Hypertext Preprocessor

Sieci Komputerowe. Laboratorium 5 - usługi sieciowe cz. 1 Maciej Szymański 28 kwietnia 2014

Wybrane działy Informatyki Stosowanej

Być może jesteś doświadczonym programistą, biegle programujesz w Javie,

SMS Kod Automatyczny

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Zawartość specyfikacji:

Usługi sieciowe systemu Linux

Laboratorium. Szyfrowanie algorytmami Vernam a oraz Vigenere a z wykorzystaniem systemu zaimplementowanego w układzie

PROBLEMATYKA BEZPIECZEŃSTWA SIECI RADIOWYCH Algorytm szyfrowania AES. Zygmunt Kubiak Instytut Informatyki Politechnika Poznańska

Języki skryptowe - PHP. PHP i bazy danych. Paweł Kasprowski. pawel@kasprowski.pl. vl07

Transkrypt:

RSA w PHP: chronimy nasze dane przy użyciu kryptografii asymetrycznej Kamil Karczmarczyk Stopień trudności: Zabezpieczenie aplikacji PHP przed włamaniami to nie wsystko: jeżeli przesyłamy dane czystym tekstem, zawsze może się znależć ktoś, kto je przechwyci podsłuchując transmisję w Internecie. Aby zadbać o bezpieczeństwo danych, musimy więc sięgnąc po kryptografię asymetryczną RSA, która daje obecnie największą pewność jego ochrony i zastosować ją zarówno po stronie serwera, jak i klienta. W SIECI 1. http://pear.php.net/package/ Crypt_RSA/ klasa Crypt_RSA (PHP) 2. http://pear.php.net/package/ Crypt_Blowfish/ klasa Crypt_Blowfish (PHP) 3. http://ohdave.com/rsa/ Implementacja RSA (JS) 4. http://en.wikipedia.org/wiki/ RSA Opis algorytmu RSA 5. http://en.wikipedia.org/wiki/ Blowfish_(cipher) Opis algorytmu Blowfish 6. http://advajax.anakin.us/ Obiekt advancedajax Nieodłączną częścią każdego mechanizmu logowania użytkowników jest przesyłanie hasła wpisanego na komputerze klienta (w przypadku aplikacji webowych w przeglądarce internetowej) na serwer, na którym (przeważnie w bazie danych) przechowywane są skróty MD5 haseł (zob. Ramka Podstawy MD5). Ponieważ te skróty są jednokierunkowe i odtworzenie haseł na ich podstawie nie jest możliwe, więc kradzież bazy nie da sprawcy wielu możliwości włamania. Poważnym problemem jest natomiast wspomniane już przesyłanie hasła jako czystego tekstu: wystarczy, aby intruz podsłuchał transmisję pomiędzy klientem a serwerem (np. za pomocą sniffera), a będzie mógł bez problemu dokonać agresji. W poprzednim numerze PHP Solutions, w artykule Kryptografia w PHP prezentowaliśmy rozwiązanie tego problemu przy użyciu algorytmu HMAC-MD5 po stronie klienta na wpisywanym haśle. Algorytm ten (w naszym przypadku zaimplementowany w języku JavaScript i działający na przeglądarce internetowej) zamienia hasło na specjalny hash, podczas generowania którego używany jest również tajny klucz. Następnie, otrzymany skrót jest wysyłany do serwera, gdzie podobnie jak przy sprawdzaniu hasła przesyłanego czystym tekstem jest porównywany z hashami zapisanymi w bazie danych. Korzystając z tej metody wyeliminujemy ryzyko Co należy wiedzieć... Należy znać podstawy programowania w PHP oraz AJAX. Przydatna będzie też podstawowa wiedza na temat kryptografii. Co obiecujemy... Pokażemy zasadę działania algorytmu asymetrycznego RSA i zademonstrujemy, jak przy jego użyciu stworzyć system bezpiecznego logowania. 2 www.phpsolmag.org

podsłuchu (nie przesyłamy samego hasła, lecz jego skrót), ale możemy jej użyć wyłącznie wobec już istniejących haseł, których skróty zostały utworzone i zapisane w bazie na serwerze. W jaki sposób więc przeprowadzimy proces rejestracji nowego konta na serwerze? Musimy w końcu przesłać na serwer informacje o nowym haśle: z oczywistych powodów nie chcemy tego robić przy użyciu czystego tekstu; przesyłanie skrótu takiego hasła również nie uchroni nas przed niebezpieczeństwem podsłuchu: ktoś, kto w tym momencie przechwyci ten skrót (rozpozna, że chodzi o dodawanie nowego konta np. po danych wysyłanych z formularza), będzie mógł go potem zwyczajnie wykorzystać przy logowaniu się na serwerze. Szyfrowanie danych za pomocą klucza symetrycznego (np.3des lub twofish) również nie wchodzi w grę, gdyż taki klucz musiałby być znany zarówno klientowi, jak i serwerowi, co oznacza konieczność jego transmisji przez Internet i czyni go podatnym na podsłuch. Jedynym sensownym rozwiązaniem problemu zabezpieczenia hasła będzie użycie asymetrycznego algorytmu szyfrującego RSA. Algorytm ten działa w oparciu o dwa klucze: publiczny (który jest ogólnie dostępny) i prywatny (dostępny wyłącznie na serwerze). Więcej informacji na temat algorytmu RSA zamieściliśmy w Ramce RSA: Zasada działania. Podstawy MD5 MD5 jest algorytmem haszującym, zwanym również jednokierunkową funkcją skrótu. W wyniku jego działania, w oparciu o podstawione dane powstaje unikalny 128-bitowy skrót. Odtworzenie danych na jego podstawie nie jest możliwe. Unikalność i jednokierunkowość działania MD5 umożliwia jego zastosowanie np. przy sprawdzaniu haseł (na serwerze zamieszczane są jedynie skróty haseł, aby uniemożliwić przechwycenie samych haseł w razie kradzieży danych), podpisywaniu plików umieszczanym w wielu repozytoriach plikom towarzyszą skróty MD5: obliczając skrót pobranego pliku i porównując go z tym zamieszczonym na serwerze możemy sprawdzić, czy archiwum nie jest uszkodzone (to samo da się zastosować np. przy porównywaniu zawartości wypalonej płyty CD lub DVD z jej obrazem, choć trwa to dość długo). Rysunek 1. Schemat działania RSA Tworzymy system bezpiecznego logowania dla aplikacji Notatki osobiste Pokażemy teraz, jak wykorzystać algorytm szyfrujący RSA w PHP, tworząc system bezpiecznego logowania dla aplikacji Notatki osobiste, która będzie służyła jako nasz osobisty notatnik online. Założenia Chcemy, aby nasza aplikacja posiadała system logowania poszczególnych użytkowników oraz możliwość dodawania nowych kont. Każdy posiadacz konta będzie mógł wyświetlać swoje notatki, a także dodawać nowe. Cała komunikacja pomiędzy klientem a serwerem będzie szyfrowana. Przygotowania Tworząc nasz system bezpiecznego logowania skorzystamy z gotowych implementacji algorytmów szyfrowania, zarówno tych działających po stronie serwera (w PHP), jak i klienta (w języku JavaScript). W pierwszym przypadku, do szyfrowania za pomocą RSA posłuży nam klasa Crypt_RSA z repozytorium PEAR (pear.php.net). Po stronie klienta użyjemy natomiast implementacji algorytmu RSA w języku JavaScript umieszczonej na stronie http://ohdave.com/rsa/. Musimy z niej pobrać pliki: BigInt.js, Barrett.js oraz RSA.js. Wymianę danych będziemy obsługiwać przy pomocy technologii AJAX, a konkretnie projektu advajax (zarówno o tym projekcie, jak i o technologii AJAX pisaliśmy w numerze 1/2006). Pobieramy więc plik advajax.js ze strony http://advajax.anakin.us i zabieramy się do pracy. Rejestracja kont Obsługą procesu rejestracji nowych kont zajmą się trzy pliki: register.php będzie odpowiadał za wyświetlenie formularza zakładania konta wraz z wygenerowanym wcześniej kluczem publicznym, RSA: Zasada działania RSA to pierwszy (wynaleziony w 1977 roku) i obecnie najpopularniejszy algorytm szyfrowania asymetrycznego, używany powszechnie np. w handlu elektronicznym czy w celu podpisywania emaili. Zasadę działania algorytmu RSA przedstawiamy na Rysunku 1. Jego idea (jak każdego szyfru asymetrycznego) polega na użyciu dwóch k luczy: publicznego i prywatnego. Oba z nich są generowane przez odbiorcę wiadomości, po czym klucz publiczny jest jawnie przesyłany nadawcy wiadomości, może też być zamieszczony np. na stronie WWW do pobrania. Nadawca szyfruje tekst za pomocą klucza publicznego i wysyła go odbiorcy. Zaszyfrowany tekst można z kolei odszyfrować tylko kluczem prywatnym, który posiada odbiorca. Nie wnikając w teorię matematyczną, która leży u podstaw RSA, warto zapamiętać, że klucz publiczny składa się z dwóch części: wykładnika publicznego (ang. public exponent) i modułu (ang. modulus), a klucz prywatny z wykładnika prywatnego (ang. private exponent) i tego samego modułu te informacje będą nam potrzebne później, gdy będziemy korzystali z klas PEAR-owych do obsługi RSA. www.phpsolmag.org 3

Listing 1. Plik register.php generowanie kluczy i wyswietlenie formularza <?php session_start(); // generowanie pary kluczy require_once 'Crypt/RSA.php'; $key_pair = new Crypt_RSA_KeyPair(512); $public_key = $key_pair->getpublickey(); $private_key = $key_pair->getprivatekey(); $enc_exp = $public_key->getexponent(); $dec_exp = $private_key->getexponent(); $modulus = $public_key->getmodulus(); // zapamiętanie danych do późniejszego dekodowania $_SESSION['rsa']=serialize($key_pair); // konwersja danych do szyfrowania na kod szesnastkowy (heksadecymalny) $enc_exponent = bin2hex($enc_exp); $mod = bin2hex($modulus);?> <html> <head> <title>mynotes - registration</title> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <script type="text/javascript" src="advajax.js"></script> <script type="text/javascript" src="bigint.js"></script> <script type="text/javascript" src="barrett.js"></script> <script type="text/javascript" src="rsa.js"></script> <!-- skrypt obsługujący formularz za pomocą AJAX --> <script type="text/javascript" src="register.js"></script> <script type="text/javascript"> var enc_exp = "<?=$enc_exponent?>"; var modulus = "<?=$mod?>"; </script> </head> <body onload="updateobjects()"> <b>mynotes - Registration</b><br/> <form method="post" action="register2.php" id="registerform"> <label for="username">login: <input type="text" name="username" id="username" /><br/> <label for="password">password: <input type="password" name="password" id="password" /><br/> <label for="name">e-mail: <input type="text" name="email" id="email" /><br/> <label for="name">name: <input type="text" name="name" id="name" /><br/> <label for="surname">surname: <input type="text" name="surname" id="surname" /><br/> <input type="submit" value="register" id="submitbtn" /> </form> <div style="margin-top: 10px" id="response"></div> </body> </html> register.js będzie w nim następowało szyfrowanie danych zawartych w formularzu oraz ich wysyłanie na serwer, register2.php w tym pliku nastąpi odszyfrowanie danych i założenie konta. Generowanie kluczy Spójrzmy na Listing 1, na którym zamieściliśmy plik register.php. Zaczniemy od wygenerowania pary kluczy (publicznego i prywatnego) poprzez utworzenie obiektu $key_pair klasy Crypt_RSA_KeyPair oraz użycie jej metod getpublickey() i getprivatekey(). Oba wygenerowane klucze stanowią osobne obiekty, z których następnie wydobywamy oba wspomniane wcześniej (zob. Ramka RSA: zasada działania) wykładniki (getexponent()) oraz moduł (getmodulus()). Następnie serializujemy (serialize()) i zapisujemy w sesji obiekt $key_pair do późniejszego wykorzystania oraz konwertujemy klucz publiczny (a właściwie jego wykładnik i moduł) z postaci binarnej na wartość szesnastkową (bin2hex()), ponieważ algorytm RSA, z którego będziemy korzystać po stronie przeglądarki, wymaga podania danych dotyczących klucza właśnie w takim formacie. Po wykonaniu tych operacji przechodzimy do generowania formularza dodawania konta (kod HTML). Jedynym dynamicznym elementem, który umieścimy w tym kodzie, będzie osadzony w prezentowanym pliku fragment skryptu JavaScript, który odpowiada za dołączenie plików: advajax.js, BigInt.js, Barrett.js i RSA.js oraz utworzenie zmiennych Java- Script enc_exp i modulus, przechowujących wartość wykładnika publicznego (szyfrującego) i modułu. Szyfrowanie Spójrzmy teraz na Listing 2, na którym przedstawiamy napisany w języku Java- Script obiekt updateobjects() (pamiętajmy, że w JavaScript nie ma klas, tylko pojedyncze obiekty, definiowane analogicznie, jak funkcje). Będzie on wywoływany przy wystąpieniu zdarzenia onload zdefiniowanego w znaczniku <body>, czyli po każdym załadowaniu strony WWW umieszczonej pomiędzy <body> a </body>. Wewnątrz updateobjects() tworzymy parę kluczy RSA, czyli obiekt RSAKeyPair, na podstawie publicznego wykładnika i modułu. Prywatny wykładnik nie jest nam potrzebny, więc wpisujemy 0. Następnie wdrażamy 4 www.phpsolmag.org

obsługę formularza za pomocą obiektu advajax. Metoda assign pobiera (jako parametr) nazwę formularza oraz obiekt zawierający metody jego obsługi. Funkcja OnInitialization jest wykonywana jeszcze przed wysłaniem formularza. To w niej następuje szyfrowanie przesyłanych danych, czyli wartości wszystkich pól formularza (nazwy użytkownika, hasła, adresu email, imienia i nazwiska) Listing 2. Plik register.js szyfrowanie i wysyłanie danych function updateobjects() { var key; key = new RSAKeyPair(enc_exp,0,modulus); function $(id) { return document.getelementbyid(id); advajax.assign($("registerform"), { oninitialization : function(obj) { // szyfrowanie danych z formularza obj.parameters["username"]=encryptedstring( key,obj.parameters["username"]); obj.parameters["password"]=encryptedstring( key,obj.parameters["password"]); obj.parameters["email"]=encryptedstring(key,obj.parameters["email"]); obj.parameters["name"]=encryptedstring(key,obj.parameters["name"]); obj.parameters["surname"]=encryptedstring(key,obj.parameters["surname"]);, $("response").innerhtml=obj.responsetext;, onerror : function() { alert("can't connect to server."); ); Listing 3. Plik register2.php deszyfrowanie i zapisanie danych nowego usera <?php session_start(); require_once 'Crypt/RSA.php'; // odczytanie przechowywanego obiektu (kluczy) $rsa_keys = unserialize($_session['rsa']); $priv = $rsa_keys->getprivatekey(); $rsa_obj = new Crypt_RSA; // deszyfrowanie $username=$rsa_obj->decryptbinary(hex2bin($_post['username']),$priv); $password=$rsa_obj->decryptbinary(hex2bin($_post['password']),$priv); $email = $rsa_obj->decryptbinary(hex2bin($_post['email']),$priv); $name = $rsa_obj->decryptbinary(hex2bin($_post['name']),$priv); $surname = $rsa_obj->decryptbinary(hex2bin($_post['surname']),$priv); // tworzenie nowego konta $user = new user; $result = $user->register($username,$password,$email,$name,$surname); if ($result) { echo "Your account are successfully created."; else { echo "error: your account can't created!";?> Listing 4. Funkcja hex2bin function hex2bin($hex) { $str=""; for($i=0;$i<strlen($hex);$i=$i+2) { $str.=chr(hexdec(substr($hex,$i,2))); return $str; za pomocą algorytmu RSA. Funkcja onsuccess wyświetla wewnątrz znacznika <div> (o id= response ) dane zwrócone przez plik register2.php, do którego wysłaliśmy wprowadzone w formularzu wartości. Deszyfrowanie i tworzenie konta Przejdźmy do omówienia zawartości wspomnianego już pliku register2.php (Listing 3). Otrzymuje on przekazane za pomocą advajax dane z formularza, które musimy teraz odszyfrować. Posłużymy się do tego zapisanym wcześniej w sesji jako rsa obiektem $key_pair, który nazwiemy $rsa_keys i zdeserializujemy (unserialize()). Następnie wydobędziemy z tego obiektu klucz prywatny, który także będzie obiektem o nazwie $priv. Potem utworzymy nowy obiekt $rsa_obj klasy Crypt_RSA i wywołujemy jego metodę DecryptBinary() odpowiedzialną za deszyfrowanie danych (każdego z przesłanych pól formularza z osobna). Metoda ta przyjmuje dwa parametry: zaszyfrowany tekst oraz utworzony przez nas wcześniej klucz prywatny $priv (obiekt klasy Crypt_RSA_ KeyPair). Ponieważ dane pochodzące z formularza zostały po zaszyfrowaniu przekonwertowane na system szesnastkowy, więc musimy je przywrócić do formy binarnej przy użyciu funkcji hex2bin(), którą napiszemy sami (Listing 4), gdyż nie została ona zaimplementowana w PHP. Mając odszyfrowane dane użytkownika, możemy przystąpić do jego rejestracji w serwisie. Robimy to np. przy pomocy klasy user, której implementację pominęliśmy, gdyż nie jest ona istotna dla ukazania technik kryptograficznych. Kryptografia hybrydowa Jako kryptografia hybrydowa rozumiane jest jednoczesne użycie kryptografii symetrycznej i asymetrycznej. Dotychczas szyfrowaliśmy dane tylko w jednym kierunku: od użytkownika do serwera. Aby zrealizować nasz projekt, będziemy jednak potrzebowali szyfrowania dwukierunkowego, gdyż w jedną stronę będziemy wysyłali nasz login i hasło oraz dodawali nowe notatki, a w drugą wyświetlali istniejące notatki. Zabezpieczenie danych przy tych czynnościach za pomoca samego RSA byłoby trudne, wykorzystamy więc dodatkowo symetryczny algorytm blowfish. Przygotowania Będziemy więc potrzebowali implementacji algorytmu blowfish. W PHP posłużymy się do tego klasą Crypt_Blowfish z repozytorium PEAR. Po stronie przeglądarki internetowej, obsługą blowfisha zajmie się plik encrypt.js, który możemy pobrać ze strony www.farfarfar.com lub www.phpsolmag.org 5

Listing 5. Formularz logowania //... <script type="text/javascript" src="encrypt.js"></script> //... <body onload="updateobjects()"> <b>mynotes - Your own on-line notices</b><br/> <div id="html"> <form method="post" action="index2.php" id="loginform"> <label for="username">login: <input type="text" name="username" id="username" /><br/> <label for="password">password: <input type="password" name="password" id="password" /><br/> <input type="hidden" name="blowfish" id="blowfish" value="" /> <input type="submit" value="login" id="submitbtn" /> </div> Listing 6. index.js obsługa AJAX function updateobjects() { // tworzenie klucza publicznego var key; key = new RSAKeyPair(enc_exp,0,modulus); // tworzenie klucza symetrycznego var blowfishkey = ""; var chars="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789" var i; for (i=0; i<25; i++) { blowfishkey += chars.charat(math.floor(math.random()*62)) document.forms["loginform"].elements["blowfish"].value=blowfishkey; function $(id) { return document.getelementbyid(id); advajax.assign($("loginform"), { oninitialization : function(obj) { // szyfrowanie danych z formularza (RSA)) obj.parameters["username"] = encryptedstring(key, obj.parameters["usernam e"]); obj.parameters["password"] = encryptedstring(key, obj.parameters["passwor d"]); obj.parameters["blowfish"] = encryptedstring(key, blowfishkey);, // deszyfrowanie blowfish $("html").innerhtml = securedecrypt(obj.responsetext, blowfishkey); ); advajax.assign($("addnoteform"), { oninitialization : function(obj) { // szyfrowanie blowfish obj.parameters["title"] = secureencrypt(obj.parameters["title"], blowfishkey); obj.parameters["note"] = secureencrypt(obj.parameters["note"], blowfishkey);, $("html").innerhtml = obj.responsetext; ); function goto(page, pageid=0) { advajax.post({ url : "index2.php?page="+page+"&pageid="+pageid, $("html").innerhtml = securedecrypt(obj.responsetext, blowfishkey); ); bezpośrednio z http://limak.blg.pl/crypto/ encrypt.js. Cała nasza aplikacja, podobnie jak to było w przypadku rejestracji, będzie się składała z trzech plików: index.php, index.js i index2.php, których zadanie jest analogiczne do plików z poprzedniego przykładu. Logowanie Spójrzmy na Listing 5. Przedstawiamy na nim fragment pliku index.php w miejscu, w którym różni się on od register.php. Dołączamy w nim też skrypt encrypt.js w języku JavaScript, który odpowiada za szyfrowanie i deszyfrowanie algorytmem blowfish. Tym razem zagnieździmy nasz formularz wewnątrz znacznika <div>, któremu nadamy id html: później będziemy dynamicznie zastępowali ten fragment kodu inną treścią. Obsługa AJAX Różnice między plikiem index.js a register.js są znacznie większe, niż pomiędzy index.php a register.php. Na Listingu 6 prezentujemy obsługę praktycznie całej szyfrowanej wymiany pomiędzy plikami index.php i index2.php. Tworzymy w nim zarówno klucz asymetryczny dla algorytmu RSA, jak i losowy ciąg znaków będący kluczem symetrycznym blowfish. Następnie korzystamy ze znanego już nam obiektu advajax, który występuje trzykrotnie. Pierwszy raz odwołuje się do formularza loginform (advajax.assign) i za pomocą RSA szyfruje login, hasło oraz dodatkowo wygenerowany klucz blowfish, a następnie przekazuje je do pliku login2.php. Od tej pory, po otrzymaniu klucza blowfish przez serwer, wymiana szyfrowanych danych odbywa się przy pomocy algorytmu symetrycznego. RSA było potrzebne jedynie do przesłania symetrycznego klucza. Gdy teraz będziemy chcieli wyświetlić wszystkie nasze notatki, wywołamy funkcję goto() z parametrem note, aby w odpowiedzi z pliku index2.php otrzymać zaszyfrowany fragment kodu odpowiedzialny za ich wyświetlenie. To, w jaki sposób plik index2.php szyfruje dane, widzimy na Listingu 7. Aby odpowiednio zaszyfrować i odszyfrować dane, po stronie przeglądarki używamy w skrypcie JavaScript funkcji secureencrypt() i securedecrypt(), natomiast w PHP wykorzystujemy PE- AR-ową klasę Crypt_Blowfish, która 6 www.phpsolmag.org

Listing 7. Zawartość pliku index2.php <?php session_start(); require_once 'Crypt/RSA.php'; require_once 'Crypt/Blowfish.php'; echo "<a href=\"javascript:goto('notes')\">my notes</a> "; echo "<a href=\"javascript:goto('addnote')\">add note</a> "; echo "<a href=\"javascript:goto('logout')\">logout</a><br/><br/>"; if(!isset($_get['page'])) { // logowanie $rsa_keys = unserialize($_session['rsa']); $priv = $rsa_keys->getprivatekey(); $rsa_obj = new Crypt_RSA; $username = $rsa_obj->decryptbinary(hex2bin($_post['username']),$priv); $password = $rsa_obj->decryptbinary(hex2bin($_post['password']),$priv); $blowfishkey = $rsa_obj->decryptbinary(hex2bin($_post['blowfish']),$priv); $_SESSION['username'] = $username; $_SESSION['password'] = $password; $_SESSION['blowfishKey'] = $blowfishkey; $user = new user($username, $password); $notes = $user->getnotes(); $html=""; foreach ($notes as $note) { $html.="<a href=\"javascript:goto('note','".$note['id']."')\">"; $html.=$note['title']."</a><br/>"; $blowfish = new Crypt_Blowfish($blowfishKey); echo(base64_encode($blowfish->encrypt($html))); else if ($_GET['page']=="addnote") { // wyświetlanie formularza $html = <<<heredochtml <form method="post" action="index2.php=addnote2" id="addnoteform"> <label for="title">title: <input type="text" name="title" id="title" /><br/> <textarea name="note" id="note"></textarea><br/> <input type="submit" value="add" id="submitbtn" /> </form> heredochtml; $blowfish = new Crypt_Blowfish($_SESSION['blowfishKey']); echo(base64_encode($blowfish->encrypt($html))); else if ($_GET['page']=="addnote2") { // dodawanie notatki $user = new user($_session['username'], $_SESSION['password']); jest bardzo intuicyjna i prosta w użyciu. Z listingów możemy wywnioskować, że sam proces przesyłania nowej notatki w formie zaszyfrowanej (obiekt advajax z parametrem odwołującym się do formularza AddNoteForm) oraz jej deszyfrowanie z poziomu PHP jest praktycznie identyczny, jak w przypadku pobierania istniejącej notatki z serwera, tyle że kolejność wykonywania czynności jest odwrotna. Podsumowanie W przedstawionej aplikacji pokazaliśmy, w jaki sposób można skorzystać z dwóch metod kryptograficznych (asymetrycznej i symetrycznej) i podaliśmy przykładowe zastosowanie tych technik. Potęga RSA w połączeniu z prostotą języka PHP oraz całkiem niezłą funkcjonalnością Java- Scriptu umożliwia tworzenie naprawdę bezpiecznych aplikacji, które będą odporne na podsłuch i przechwytywanie danych. Zachęcamy do korzystania z kryptografii we własnych projektach zwłaszcza tam, gdzie poufność przesyłanych i gromadzonych danych jest szczególnie istotna, poczynając od aplikacji do gromadzenia prywatnych notatek i systemów przekazywania wiadomości osobistych, poprzez narzędzia używane wewnątrz firmy (np. do zarządzania projektem, danymi księgowymi czy biznesplanem), po dostępne dla tysięcy użytkowników jednocześnie systemy e-commerce, takie jak sklepy internetowe czy pasaże aukcyjne. Na pohybel intruzom! // ustawienie klucza blowfish $blowfish = new Crypt_Blowfish($_SESSION['blowfishKey']); //deszyfrowanie blowfish $title = $blowfish->decrypt(base64_decode($_post['title'])); $notetext = $blowfish->decrypt(base64_decode($_post['note'])); //dodawanie notki $user->addnote($title,$notetext); echo "new note added"; else if (($_GET['page']=="note")&&(isset($_GET['pageid']))) { // wyświetlanie notki $user = new user($_session['username'], $_SESSION['password']); $note = $user->getnotebyid($_get['pageid']); $html = "<b>".$note['title']."</b><br/>"; $html.= "<p>".$note['text']."</p>"; $blowfish = new Crypt_Blowfish($_SESSION['blowfishKey']); echo(base64_encode($blowfish->encrypt($html)));?> O autorze Kamil Karczmarczyk jest uczniem Liceum Ogólnokształcącego. Od kilku lat hobbystycznie zajmuje się programowaniem, między innymi w PHP. Interesuje się bezpieczeństwem sieci, kryptografią oraz matematyką. Kontakt z autorem: limak@mmj.pl www.phpsolmag.org 7