Ten przewodnik pokaże Ci, jak bezpiecznie przechowywać swoje sesje w bazie danych mySQL. Zaszyfrujemy również wszystkie dane sesji, które trafiają do bazy danych, co oznacza, że jeśli komuś uda się włamać do bazy danych, wszystkie dane sesji są szyfrowane 256-bitowym szyfrowaniem AES.
Kroki
Metoda 1 z 3: Skonfiguruj bazę danych mySQL
Krok 1. Utwórz bazę danych MySQL
W tym przewodniku stworzymy bazę danych o nazwie „secure_sessions”.
Zobacz, jak utworzyć bazę danych w phpMyAdmin.
Lub możesz użyć poniższego kodu SQL, aby utworzyć go dla Ciebie.
Utwórz kod bazy danych:
TWORZENIE BAZY DANYCH `secure_sessions`;
Uwaga: Niektóre usługi hostingowe nie pozwalają na tworzenie bazy danych za pośrednictwem phpMyAdmin, Dowiedz się, jak to zrobić w cPanel.
Krok 2. Utwórz użytkownika z uprawnieniami SELECT, INSERT i DELETE
Oznacza to, że gdyby kiedykolwiek doszło do naruszenia bezpieczeństwa w naszym skrypcie, haker nie mógł usunąć tabel z naszej bazy danych. Jeśli naprawdę masz paranoję, stwórz innego użytkownika dla każdej funkcji.
-
Użytkownik:
"sec_user"
-
Hasło:
„eKcGZr59zAa2BEWU”
Utwórz kod użytkownika:
UTWÓRZ UŻYTKOWNIKA 'sec_user'@'localhost' IDENTYFIKOWANEGO PRZEZ 'eKcGZr59zAa2BEWU'; PRZYZNAJ WYBÓR, WSTAW, AKTUALIZUJ, USUŃ NA `secure_sessions`.* TO 'sec_user'@'localhost';
Uwaga: Dobrym pomysłem jest zmiana hasła w powyższym kodzie podczas pracy na własnym serwerze. (Upewnij się, że zmieniłeś również kod PHP.) Pamiętaj, że nie musi to być hasło, które możesz zapamiętać, więc make jest tak skomplikowane, jak to tylko możliwe. Oto generator losowych haseł.
Krok 3. Utwórz tabelę MySQL o nazwie „sesje”
Poniższy kod tworzy tabelę z 4 polami (id, set_time, data, session_key).
Utwórz tabelę „sesje”:
CREATE TABLE `sessions` (`id` char(128) NOT NULL, `set_time` char(10) NOT NULL, `data` text NOT NULL, `session_key` char(128) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Używamy typu danych CHAR dla pól, których długość znamy, ponieważ pola "id" i "session_key" zawsze będą miały długość 128 znaków. Użycie tutaj CHAR oszczędza moc obliczeniową.
Metoda 2 z 3: Utwórz plik session.class.php
Krok 1. Utwórz klasę
Aby rozpocząć nowe zajęcia, musisz wpisać poniższy kod:
Nowa klasa:
sesja klasowa {
Krok 2. Utwórz funkcję _construct
Ta funkcja będzie wywoływana za każdym razem, gdy tworzymy nową instancję obiektu przy użyciu klasy 'session'. Możesz przeczytać o funkcji PHP _construct tutaj.
Ta funkcja ustawia nasz niestandardowy program obsługi sesji, aby był dostępny do użycia, gdy tylko zostanie utworzona instancja klasy (tj. zostanie wykonana/zbudowana/skonstruowana).
_funkcja konstrukcji:
function _construct() { // ustaw nasze niestandardowe funkcje sesji. session_set_save_handler(array($this, 'otwórz'), array($this, 'zamknij'), array($this, 'odczytaj'), array($this, 'zapisz'), array($this, 'zniszcz'), tablica($to, 'gc')); // Ten wiersz zapobiega nieoczekiwanym efektom podczas używania obiektów jako programów obsługi składowania. register_shutdown_function('session_write_close'); }
Krok 3. Utwórz funkcję start_session
Ta funkcja będzie wywoływana za każdym razem, gdy będziesz chciał rozpocząć nową sesję, użyj jej zamiast session_start();. Zobacz komentarze w kodzie, aby zobaczyć, co robi każda linia.
funkcja start_session:
function start_session($session_name, $secure) { // Upewnij się, że plik cookie sesji nie jest dostępny przez JavaScript. $httptylko = prawda; // Algorytm haszujący do użycia w sesji. (użyj hash_algos(), aby uzyskać listę dostępnych skrótów.) $session_hash = 'sha512'; // Sprawdź, czy hash jest dostępny if (in_array($session_hash, hash_algos())) { // Ustaw funkcję has. ini_set('sesja.hash_function', $session_hash); } // Ile bitów przypada na znak skrótu. // Możliwe wartości to '4' (0-9, a-f), '5' (0-9, a-v) i '6' (0-9, a-z, A-Z, "-", ", "). ini_set('sesja.hash_bits_per_character', 5); // Wymuś w sesji używanie tylko plików cookie, a nie zmiennych URL. ini_set('session.use_only_cookies', 1); // Pobierz parametry ciasteczek sesji $cookieParams = session_get_cookie_params(); // Ustaw parametry session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); // Zmień nazwę sesji session_name($session_name); // Teraz zaczynamy sesję session_start(); // Ta linia regeneruje sesję i usuwa starą. // Generuje również nowy klucz szyfrowania w bazie danych. session_regenerate_id (prawda); }
Krok 4. Utwórz otwartą funkcję
Ta funkcja będzie wywoływana przez sesje PHP, gdy rozpoczynamy nową sesję, używamy jej do uruchomienia nowego połączenia z bazą danych.
otwarta funkcja:
function open() { $host = 'localhost'; $user = 'sec_user'; $pass = 'eKcGZr59zAa2BEWU'; $name = 'bezpieczne_sesje'; $mysqli = nowe mysqli($host, $użytkownik, $pass, $nazwa); $to->db = $mysqli; zwróć prawdę; }
Krok 5. Utwórz funkcję zamykania
Ta funkcja zostanie wywołana, gdy sesje będą chciały zostać zamknięte.
funkcja zamykania:
funkcja close() { $this->db->close(); zwróć prawdę; }
Krok 6. Utwórz funkcję odczytu
Ta funkcja zostanie wywołana przez PHP, gdy spróbujemy uzyskać dostęp do sesji, na przykład, gdy użyjemy echo $_SESSION['coś'];. Ponieważ na jednej stronie może być wiele wywołań tej funkcji, korzystamy z przygotowanych instrukcji nie tylko ze względów bezpieczeństwa, ale także wydajności. Oświadczenie przygotowujemy tylko raz, potem możemy je wykonywać wielokrotnie.
Odszyfrowujemy również dane sesji, które są zaszyfrowane w bazie danych. W naszych sesjach używamy 256-bitowego szyfrowania AES.
funkcja odczytu:
function read($id) { if(!isset($this->read_stmt)) { $this->read_stmt = $this->db->prepare("SELECT data FROM session WHERE id = ? LIMIT 1"); } $this->read_stmt->bind_param('s', $id); $this->read_stmt->execute(); $this->read_stmt->store_result(); $this->read_stmt->bind_result($data); $this->read_stmt->fetch(); $klucz = $to->getkey($id); $dane = $to->odszyfrować($dane, $klucz); zwróć $dane; }
Krok 7. Utwórz funkcję zapisu
Ta funkcja jest używana, gdy przypisujemy wartość do sesji, na przykład $_SESSION['coś'] = 'coś innego';. Funkcja szyfruje wszystkie dane, które trafiają do bazy danych.
funkcja zapisu:
function write($id, $data) { // Uzyskaj unikalny klucz $key = $this->getkey($id); // Zaszyfruj dane $data = $this->encrypt($data, $key); $czas = czas(); if(!isset($this->w_stmt)) { $this->w_stmt = $this->db->prepare("ZASTĄP W sesje (id, set_time, data, session_key) WARTOŚCI (?, ?, ?, ?)"); } $this->w_stmt->bind_param('siss', $id, $time, $data, $key); $this->w_stmt->execute(); zwróć prawdę; }
Krok 8. Utwórz funkcję zniszczenia
Ta funkcja usuwa sesję z bazy danych, jest używana przez php, gdy wywołujemy funkcje takie jak session_destroy();.
funkcja zniszczenia:
function destroy($id) { if(!isset($this->delete_stmt)) { $this->delete_stmt = $this->db->prepare("USUŃ Z sesji GDZIE id = ?"); } $this->delete_stmt->bind_param('s', $id); $this->delete_stmt->execute(); zwróć prawdę; }
Krok 9. Utwórz funkcję gc (garbage collector)
Ta funkcja jest funkcją odśmiecania pamięci i jest wywoływana w celu usunięcia starych sesji. Częstotliwość wywoływania tej funkcji jest określona przez dwie dyrektywy konfiguracyjne: session.gc_probability i session.gc_divisor.
funkcja gc():
function gc($max) { if(!isset($this->gc_stmt)) { $this->gc_stmt = $this->db->prepare("USUŃ Z sesji GDZIE set_time <?"); } $stary = czas() - $maks; $this->gc_stmt->bind_param('s', $old); $this->gc_stmt->execute(); zwróć prawdę; }
Krok 10. Utwórz funkcję getKey
Ta funkcja służy do uzyskania unikalnego klucza do szyfrowania z tabeli sesji. Jeśli nie ma sesji, po prostu zwraca nowy losowy klucz do szyfrowania.
getkey() Funkcja:
private function getkey($id) { if(!isset($this->key_stmt)) { $this->key_stmt = $this->db->prepare("SELECT session_key FROM session WHERE id =? LIMIT 1"); } $this->key_stmt->bind_param('s', $id); $this->key_stmt->execute(); $this->key_stmt->store_result(); if($this->key_stmt->num_rows == 1) { $this->key_stmt->bind_result($key); $this->key_stmt->fetch(); zwróć $klucz; } else { $random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true)); zwróć $losowy_klucz; } }
Krok 11. Utwórz funkcje szyfrowania i odszyfrowywania
Funkcje te szyfrują dane sesji, używają klucza szyfrującego z bazy danych, który jest inny dla każdej sesji. Nie używamy tego klucza bezpośrednio do szyfrowania, ale używamy go, aby skrót klucza był jeszcze bardziej losowy.
funkcje encrypt() i decrypt():
private function encrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHEGE*ewr4n39=E@rAsp7c-Ph@pH'; $klucz = substr(hash('sha256', $salt.$key.$salt), 0, 32); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $klucz, $dane, MCRYPT_MODE_ECB, $iv)); zwróć $zaszyfrowane; } private function decrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH'; $klucz = substr(hash('sha256', $salt.$key.$salt), 0, 32); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $ odszyfrowane = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $klucz, base64_decode($dane), MCRYPT_MODE_ECB, $iv); $odszyfrowane = rtrim($odszyfrowane, "\0"); zwróć $odszyfrowane; }
Krok 12. Zakończ zajęcia
Tutaj po prostu kończymy nawiasy klamrowe klas:
Klasa końcowa:
}
Metoda 3 z 3: Tworzenie stron z sesjami
Krok 1. Korzystanie z sesji z niestandardowym menedżerem sesji
Poniżej znajduje się sposób rozpoczęcia nowej sesji; musiałbyś umieścić to na każdej stronie, na której chcesz uzyskać dostęp do sesji, użyj go zamiast session_start();
Rozpoczęcie sesji:
wymagaj('sesja.class.php'); $sesja = nowa sesja(); // Ustaw na true jeśli używasz https $session->start_session('_s', false); $_SESSION['coś'] = 'Wartość'; echo $_SESSION['coś'];