Vous êtes sur la page 1sur 6

<?php /************************************************************** A Crude Model for Encrypted MySQL-based PHP Sessions Copyright 2004 (c) Ido Rosen <ido+code@cs.uchicago.

edu> All rights reserved. This code is provided under the following license: --LICENSE: Any use of this code for profit or any use of this code of any commercial nature is strictly prohibited unless given express consent of the author, Ido Rosen. This code is free for personal non-profit use. --Consent may be obtained for commercial uses of this code by submitting a $10 donation to the author at the following URL: http://www.cs.uchicago.edu/~ido/donate.php All donations go toward the author's education. Immediately following your donation, you will receive a PGP-signed email from the author (signed by keyID 45C024FD) granting you permission to use the code commercially or for whatever purposes you wish. Donations of larger sums are encouraged if you find this code especially useful or wish to support my education. (Please don't just steal my code. :) Furthermore, the author is available for hire should the need for his expertise arise. Feel free to contact him via email at ido+code@cs.uchicago.edu. Best wishes, Ido. **************************************************************/ // Instructions for use: // Just include this file: include_once("session_include.php"); // (after renaming it appropriately, of course!) // Site configuration variables. $DBHOST $DBUSER $DBPASS $DBNAME = = = = "localhost"; "test"; "test"; "test";

$SITESESSNAME = "HBC_SESS" // All session data is encrypted. To change the key, simply add another // RIJNDAEL256_x entry (x=some number not already chosen) // then add the appropriate entries in the switch parts of sess_encrypt/decrypt

// then modify the CURRENT KEY NAME line way down below. // Have fun!!! $sess_key = Array("PLAINTEXT"=>NULL, "ROT13"=>NULL, "RIJNDAEL256_1"=> "INSERT YOUR PASSPHRASE HERE -- preferrably a randomly-generated one. you don't need to remember it, since it's stored in t he code."); // arbitrary, relatively big password // End site configuration. Don't change anything below this line. // IP address of client can be gotten with getenv("REMOTE_ADDR") // IP address of client can be gotten with getenv("REMOTE_ADDR") // Database and Session Management Code if (!function_exists("mysql_connect")) { die("Database libraries not found..."); } global $dblink; $dblink = ""; // 2048 = CLIENT_SSL in MySQL 4.0 C libraries, pseudo-hack for MySQL over SSL. if (!isset($DBHOST) !isset($DBUSER)) $dblink = @mysql_pconnect(); else $dblink = @mysql_pconnect($DBHOST, $DBUSER, $DBPASS); if (!$dblink) die("Error connecting to database..."); if (!@mysql_select_db($DBNAME, $dblink)) die("Error connecting to database..."); function db_connected() { global $dblink; if (!mysql_ping($dblink)) die("Database connection lost..."); else return true; } // Session Crypto Functions (ADVANCED!) function SymmetricEncrypt($pt,$pw, $cipher, $hash) { $realkey = mhash($hash,$pw); $td = @mcrypt_module_open($cipher, "", MCRYPT_MODE_OFB, ""); $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM); @mcrypt_generic_init($td, $realkey, $iv); $blob = @mcrypt_generic($td, mhash($hash,$pt). $pt); @mcrypt_generic_end($td); return base64_encode($iv. $blob); } function SymmetricDecrypt($blob, $pw, $cipher, $hash) { $realkey=mhash($hash,$pw); $rawblob=base64_decode($blob); /* binary blob */ $td = mcrypt_module_open($cipher, "", MCRYPT_MODE_OFB, ""); $iv=substr($rawblob,0,mcrypt_enc_get_iv_size($td)); /* IV */

if (strlen($iv)<mcrypt_enc_get_iv_size($td)) return FALSE; $ct=substr($rawblob,mcrypt_enc_get_iv_size($td)); /* CipherText */ mcrypt_generic_init($td, $realkey, $iv); $unblob=mdecrypt_generic($td,$ct); mcrypt_generic_end($td); $pt=substr($unblob,mhash_get_block_size($hash)); $check=substr($unblob,0,mhash_get_block_size($hash)); if ($check != mhash($hash,$pt)) return FALSE; else return $pt; } function sess_decrypt($sessdata, $encryption, $sanityhash="", $key="") { global $sess_key; if (!$key) $key = $sess_key[$encryption]; switch($encryption) { case 'PLAINTEXT': $returnval = $sessdata; break; case 'ROT13': $returnval = str_rot13($sessdata); // For entertainment purposes... :) break; case 'RIJNDAEL256_1': $returnval = SymmetricDecrypt($sessdata, $sess_key[$encryption], MCRYPT_RIJN DAEL_256, MHASH_MD5); break; case 'RIJNDAEL256_2': $returnval = SymmetricDecrypt($sessdata, $sess_key[$encryption], MCRYPT_RIJN DAEL_256, MHASH_MD5); break; default: die("Session decryption failed..."); break; } // Check sanity if sanityhash provided... if (strlen($sanityhash) != strlen(md5(""))) return $returnval; if (md5($returnval) == ($sanityhash)) return $returnval; else die("Session decryption failed..."); } function sess_encrypt($sessdata) { $returnval = Array(); global $sess_key; // Session encryption keys for all crypto algorithms. $returnval['sanityhash'] = md5($sessdata); // For verification purposes if (!@function_exists('mcrypt_encrypt')) $returnval['encryption'] = "PLAINTEXT";

else $returnval['encryption'] = 'RIJNDAEL256_1'; // SET TO CURRENT KEY NAME. switch ($returnval['encryption']) { case 'PLAINTEXT': $returnval['crypted_sessdata'] = $sessdata; break; case 'ROT13': // For entertainment purposes... :) $returnval['crypted_sessdata'] = str_rot13($sessdata); break; case 'RIJNDAEL256_1': $returnval['crypted_sessdata'] = SymmetricEncrypt($sessdata,$sess_key[$retur nval['encryption']],MCRYPT_RIJNDAEL_256,MHASH_MD5); break; case 'RIJNDAEL256_2': $returnval['crypted_sessdata'] = SymmetricEncrypt($sessdata,$sess_key[$retur nval['encryption']],MCRYPT_RIJNDAEL_256,MHASH_MD5); break; } // Sanity check: if ((sess_decrypt($returnval['crypted_sessdata'], $returnval['encryption'])) = = $sessdata) { return $returnval; } else { $returnval['encryption'] = "PLAINTEXT"; $returnval['crypted_sessdata'] = $sessdata; return $returnval; } } // Session Handler Functions /* Session table structure: -- sid include sname in it, but for indexing purposes, include sname separately. CREATE TABLE sessions ( sid varchar(255), sname varchar(255), ip varchar(255), encryption varchar(32), sanityhash varchar(32), sessdata text, touched TIMESTAMP(14), PRIMARY KEY (sid), INDEX(sname), INDEX(ip), INDEX(touched) ); */ global $sess_maxlife; $sess_maxlife = 86400; // seconds that a session may last (86400sec = 1day) function sess_open($path,$name) { global $sess_path, $sess_name, $sess_maxlife; $sess_path = $path; $sess_name = $name;

sess_gc($sess_maxlife); return true; } function sess_close() { global $sess_path, $sess_name; sess_gc($sess_maxlife); return true; } function sess_read($sess_id) { global $sess_path, $sess_name, $dblink; $sql = "SELECT encryption, sanityhash, sessdata FROM sessions WHERE sid='".$sess_id."' AND ip='".getenv("REMOTE_ADDR")."' AND sname='".$sess_name."'"; $result = @mysql_query($sql, $dblink); if (@mysql_num_rows($result) == 1) { $sessdata = mysql_fetch_assoc($result); return sess_decrypt($sessdata['sessdata'], $sessdata['encryption'], $sessdata['sanityhash']); } else { $sql = "DELETE FROM sessions WHERE sid='$sess_id'"; @mysql_query($sql, $dblink); $sql = "INSERT INTO sessions (sid, touched, ip, encryption, sname, sanityhash, sessdata) VALUES ('".$sess_id."', NOW(), '".getenv("REMOTE_ADDR")."', 'PLAINTEXT', '".$sess_name."', '', '')"; if (!@mysql_query($sql, $dblink)) die("Error creating session..."); return ""; } } function sess_write($sess_id,$sess_data) { global $sess_path, $sess_name, $dblink; $sess_id = $sess_name . $sess_id; $cryptdata = sess_encrypt($sess_data); $sql = "UPDATE sessions SET sessdata='".$cryptdata['crypted_sessdata']."', encryption='".$cryptdata['encryption']."', sanityhash='".$cryptdata['sanityhash']."' WHERE sid='".$sess_id."' AND ip='".getenv("REMOTE_ADDR")."' AND sname='".$sess_name."'"; @mysql_query($sql, $dblink); return true; }

function sess_destroy($sess_id) { global $sess_path, $sess_name, $dblink; $sql = "DELETE FROM sessions WHERE sid='".$sess_id."' AND sname='".$sess_name."'"; @mysql_query($sql,$dblink); return true; } function { global $max = $sql = sess_gc($maxlifetime) $sess_path, $sess_name, $sess_maxlife, $dblink; min($sess_maxlife,$maxlifetime); "DELETE FROM sessions WHERE touched>(UNIX_TIMESTAMP(NOW())-".$max.") AND sname='".$sess_name."'";

@mysql_query($sql,$dblink); return true; } // Activate above handlers: session_set_save_handler('sess_open','sess_close','sess_read','sess_write', 'sess_destroy','sess_gc'); // Initialize session: session_name($SITESESSNAME); session_start(); ?>