RSA w PHP chronimy dane przy uzyciu kryptografii
Transkrypt
RSA w PHP chronimy dane przy uzyciu kryptografii
Bezpieczeństwo RSA w PHP: chronimy nasze dane przy użyciu kryptografii asymetrycznej Stopień trudności: lll Kamil Karczmarczyk 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. N 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 2 ieodłą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 www.phpsolmag.org 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. PHP Solutions Nr 6/2006 Bezpieczeństwo 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). PHP Solutions Nr 6/2006 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 Bezpieczeństwo 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(); Generowanie kluczy $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: </label> <input type="text" name="username" id="username" /><br/> <label for="password">Password: </label> <input type="password" name="password" id="password" /><br/> <label for="name">e-mail: </label> <input type="text" name="email" id="email" /><br/> <label for="name">Name: </label> <input type="text" name="name" id="name" /><br/> <label for="surname">Surname: </label> <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> 4 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. www.phpsolmag.org 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 JavaScript 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 JavaScript 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 PHP Solutions Nr 6/2006 Bezpieczeństwo 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) 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 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"]); }, onSuccess : function(obj) { $("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!"; } ?> 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 Listing 4. Funkcja hex2bin 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 function hex2bin($hex) { $str=""; for($i=0;$i<strlen($hex);$i=$i+2) { $str.=chr(hexdec(substr($hex,$i,2))); } return $str; } PHP Solutions Nr 6/2006 (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. www.phpsolmag.org 5 Bezpieczeństwo 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:</label> <input type="text" name="username" id="username" /><br/> <label for="password">Password:</label> <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); }, onSuccess : function(obj) { // 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); }, onSuccess : function(obj) { $("html").innerHTML = obj.responseText; } }); } function goto(page, pageid=0) { advAJAX.post({ url : "index2.php?page="+page+"&pageid="+pageid, onSuccess : function(obj) { $("html").innerHTML = secureDecrypt(obj.responseText, blowfishKey); } }); } 6 www.phpsolmag.org 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 PEAR-ową klasę Crypt_Blowfish, która PHP Solutions Nr 6/2006 Bezpieczeństwo 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:</label> <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']); // 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))); } ?> PHP Solutions Nr 6/2006 www.phpsolmag.org 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ą JavaScriptu 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! n 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: [email protected] 7