Deze handleiding laat u zien hoe u uw sessies veilig kunt opslaan in een mySQL-database. We versleutelen ook alle sessiegegevens die naar de database gaan, wat betekent dat als iemand erin slaagt de database te hacken, alle sessiegegevens worden versleuteld met 256-bits AES-codering.
Stappen
Methode 1 van 3: MySQL-database configureren
Stap 1. Maak een MySQL-database
In deze handleiding zullen we een database maken met de naam "secure_sessions".
Zie hoe u een database aanmaakt in phpMyAdmin.
Of u kunt de onderstaande SQL-code gebruiken om er een voor u te maken.
Databasecode maken:
MAAK DATABASE `secure_sessions`;
Opmerking: bij sommige hostingservices kunt u geen database maken via phpMyAdmin. Leer hoe u dit doet in cPanel.
Stap 2. Maak een gebruiker aan met alleen SELECT, INSERT en DELETE privileges
Dit betekent dat als er ooit een inbreuk op de beveiliging in ons script was, de hacker geen tabellen uit onze database kon verwijderen. Als je echt paranoïde bent, maak dan voor elke functie een andere gebruiker aan.
-
Gebruiker:
"sec_gebruiker"
-
Wachtwoord:
"eKcGZr59zAa2BEWU"
Gebruikerscode aanmaken:
MAAK GEBRUIKER 'sec_user'@'localhost' GEDENTIFICEERD DOOR 'eKcGZr59zAa2BEWU'; GRANT SELECT, INSERT, UPDATE, DELETE OP `secure_sessions`.* AAN 'sec_user'@'localhost';
Opmerking: het is een goed idee om het wachtwoord in de bovenstaande code te wijzigen wanneer u op uw eigen server draait. (Zorg ervoor dat u ook uw PHP-code wijzigt.) Onthoud dat het geen wachtwoord hoeft te zijn dat u kunt onthouden, dus maak het zo ingewikkeld mogelijk. Hier is een willekeurige wachtwoordgenerator.
Stap 3. Maak een MySQL-tabel met de naam "sessions"
De onderstaande code maakt een tabel met 4 velden (id, set_time, data, session_key).
Maak de tabel "sessies" aan:
CREATE TABLE `sessions` (`id` char (128) NOT NULL, `set_time` char (10) NOT NULL, `data` tekst NOT NULL, `session_key` char (128) NOT NULL, PRIMARY KEY (`id`)) MOTOR=InnoDB STANDAARD CHARSET=latin1;
We gebruiken het datatype CHAR voor velden waarvan we de lengte kennen, aangezien de velden "id" en "session_key" altijd 128 tekens lang zullen zijn. Het gebruik van CHAR hier bespaart verwerkingskracht.
Methode 2 van 3: Maak het bestand session.class.php aan
Stap 1. Maak een klas aan
Om een nieuwe les te starten moet je onderstaande code invoeren:
Nieuwe klasse:
klas sessie {
Stap 2. Maak een _construct-functie
Deze functie wordt elke keer aangeroepen als we een nieuwe instantie van een object maken met behulp van de klasse 'session'. U kunt hier meer lezen over de PHP _construct-functie.
Deze functie stelt onze aangepaste sessie-handler in zodat deze beschikbaar is voor gebruik zodra de klasse is geïnstantieerd (d.w.z. gemaakt/gebouwd/geconstrueerd).
_construct functie:
function _construct() { // stel onze aangepaste sessiefuncties in. session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc')); // Deze regel voorkomt onverwachte effecten bij het gebruik van objecten als opslaghandlers. register_shutdown_function('session_write_close'); }
Stap 3. Maak de start_session-functie
Deze functie wordt elke keer aangeroepen als u een nieuwe sessie wilt starten, gebruik deze in plaats van session_start();. Zie de opmerkingen in de code om te zien wat elke regel doet.
start_session functie:
function start_session($session_name, $secure) { // Zorg ervoor dat de sessiecookie niet toegankelijk is via javascript. $httponly = waar; // Hash-algoritme dat voor de sessie moet worden gebruikt. (gebruik hash_algos() om een lijst met beschikbare hashes te krijgen.) $session_hash = 'sha512'; // Controleer of hash beschikbaar is if (in_array($session_hash, hash_algos())) { // Stel de has-functie in. ini_set('sessie.hash_function', $session_hash); } // Hoeveel bits per karakter van de hash. // De mogelijke waarden zijn '4' (0-9, a-f), '5' (0-9, a-v) en '6' (0-9, a-z, A-Z, "-", ", "). ini_set('sessie.hash_bits_per_character', 5); // Forceer de sessie om alleen cookies te gebruiken, geen URL-variabelen. ini_set('sessie.use_only_cookies', 1); // Sessiecookieparameters ophalen $cookieParams = session_get_cookie_params(); // Stel de parameters session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); // Wijzig de sessienaam session_name($session_name); // Nu beginnen we de sessie session_start(); // Deze regel regenereert de sessie en verwijdert de oude. // Het genereert ook een nieuwe coderingssleutel in de database. session_regenerate_id(true); }
Stap 4. Maak een open functie aan
Deze functie wordt aangeroepen door de PHP-sessies wanneer we een nieuwe sessie starten, we gebruiken deze om een nieuwe databaseverbinding te starten.
open functie:
functie open() { $host = 'localhost'; $gebruiker = 'sec_gebruiker'; $pass = 'eKcGZr59zAa2BEWU'; $name = 'secure_sessions'; $mysqli = nieuwe mysqli($host, $user, $pass, $name); $this->db = $mysqli; retourneer waar; }
Stap 5. Maak een sluitfunctie aan
Deze functie wordt aangeroepen wanneer de sessies gesloten willen worden.
sluit functie:
functie close() { $this->db->close(); retourneer waar; }
Stap 6. Creëer leesfunctie
Deze functie wordt aangeroepen door PHP wanneer we proberen toegang te krijgen tot een sessie, bijvoorbeeld wanneer we echo $_SESSION['something']; gebruiken. Omdat er op één pagina mogelijk veel aanroepen naar deze functie zijn, maken we gebruik van voorbereide instructies, niet alleen voor de veiligheid, maar ook voor de prestaties. We bereiden de instructie slechts één keer voor en kunnen deze vervolgens vele malen uitvoeren.
We decoderen ook de sessiegegevens die in de database zijn versleuteld. We gebruiken 256-bit AES-codering in onze sessies.
lees functie:
function read($id) { if(!isset($this->read_stmt)) { $this->read_stmt = $this->db->prepare("SELECTEER gegevens UIT sessies WAAR 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(); $key = $this->getkey($id); $data = $this->decrypt($data, $key); retourneer $gegevens; }
Stap 7. Schrijffunctie maken
Deze functie wordt gebruikt wanneer we een waarde aan een sessie toekennen, bijvoorbeeld $_SESSION['something'] = 'something else';. De functie versleutelt alle gegevens die in de database worden ingevoegd.
schrijf functie:
function write($id, $data) { // Krijg unieke sleutel $key = $this->getkey($id); // Versleutel de gegevens $data = $this->encrypt ($data, $key); $tijd = tijd(); if(!isset($this->w_stmt)) { $this->w_stmt = $this->db->prepare("VERVANG IN sessies (id, set_time, data, session_key) WAARDEN (?, ?, ?, ?)"); } $this->w_stmt->bind_param('siss', $id, $time, $data, $key); $this->w_stmt->execute(); retourneer waar; }
Stap 8. Maak een vernietigingsfunctie
Deze functie verwijdert de sessie uit de database, het wordt gebruikt door php wanneer we functies aanroepen zoals session_destroy();.
vernietigen functie:
function destroy($id) { if(!isset($this->delete_stmt)) { $this->delete_stmt = $this->db->prepare("VERWIJDER UIT sessies WHERE id = ?"); } $this->delete_stmt->bind_param('s', $id); $this->delete_stmt->execute(); retourneer waar; }
Stap 9. Creëer de gc-functie (vuilnisophaler)
Deze functie is de garbage collector-functie die wordt aangeroepen om oude sessies te verwijderen. De frequentie waarmee deze functie wordt aangeroepen, wordt bepaald door twee configuratierichtlijnen, session.gc_probability en session.gc_divisor.
gc() functie:
function gc($max) { if(!isset($this->gc_stmt)) { $this->gc_stmt = $this->db->prepare("VERWIJDER UIT sessies WAAR set_time <?"); } $oud = tijd() - $max; $this->gc_stmt->bind_param('s', $old); $this->gc_stmt->execute(); retourneer waar; }
Stap 10. Maak de getKey-functie
Deze functie wordt gebruikt om de unieke sleutel voor codering uit de sessietabel te halen. Als er geen sessie is, retourneert het gewoon een nieuwe willekeurige sleutel voor codering.
getkey() Functie:
private functie 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(); retourneer $sleutel; } else { $random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true)); retourneer $ willekeurige_sleutel; } }
Stap 11. Maak coderings- en decoderingsfuncties
Deze functies versleutelen de data van de sessies, ze gebruiken een encryptiesleutel uit de database die voor elke sessie anders is. We gebruiken die sleutel niet rechtstreeks in de codering, maar we gebruiken hem om de sleutelhash nog willekeuriger te maken.
encrypt() en decrypt() functies:
private functie versleutelen($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH'; $key = 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, $key, $data, MCRYPT_MODE_ECB, $iv)); retourneer $gecodeerd; } private functie decrypt($data, $key) { $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH'; $key = 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); $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv); $decrypted = rtrim($decrypted, "\0"); retourneer $gedecodeerd; }
Stap 12. Beëindig de les
Hier eindigen we gewoon de klassen accolades:
Einde klasse:
}
Methode 3 van 3: Pagina's maken met sessies
Stap 1. Sessies gebruiken met de aangepaste sessiemanager
Hieronder ziet u hoe u een nieuwe sessie zou starten; u zou dit op elke pagina moeten opnemen waarop u toegang wilt tot de sessies, gebruik het in plaats van session_start();
Een sessie starten:
vereisen('sessie.class.php'); $session = nieuwe sessie(); // Stel in op true bij gebruik van https $session->start_session('_s', false); $_SESSION['something'] = 'Een waarde.'; echo $_SESSION['iets'];