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

Podobne dokumenty