Encriptar sesiones utilizando mcrypt en php
Bueno por todos es conocido que las sesiones en php tienes sus vulnerabilidades, vaya que no son 100% efectivas en cuanto a seguridad, pues estas se almacenan en unas cookies en el servidor en cuyo caso si se tiene acceso a esta carpeta se podrían leer. Para evitarlo hay diversas maneras una es almacenando los datos de sesión en un servidor de bases de datos o codificando estas cookies.
La desventaja del primero aunque es más seguro es la saturación del servidor SQL en caso de que existan muchas variables y muchos usuarios, por eso me parece una forma segura y fiable la codificación de estas cookies.
Este código es una modificación del código de Martin Sarsale (martin@n3rds.com.ar) en el cual utiliza funciones ya deprecadas en php. Además le aumento la seguridad utilizando constantes definidas en otros archivos y el vector de inicialización.
define("INIT_VECTOR","36452318");
function sess_open($sess_path, $session_name){
global $_SEC_SESSION;
$sess_sec=ini_get('session.name')."_sec";
# aparte de la cookie de la sesion se crea otra terminada en
# '_sec' donde se almacena una clave aleatoria de 32 byte (key)
if (!isset($_COOKIE[$sess_sec])){
$md5=md5(uniqid(''));
setcookie($sess_sec,$md5,ini_get('session.cookie_lifetime'),
ini_get('session.cookie_path'),
ini_get('session.cookie_domain'));
$_SEC_SESSION['int']['key']=$_COOKIE[$sess_sec]=$md5;
$_SEC_SESSION['data']=serialize(array());
$empty=1;
}
else
$_SEC_SESSION['int']['key']=$md5=$_COOKIE[$sess_sec];
# el nombre del archivo que contendrá la infrmación de la sesión empieza,
# con 'sec_sess_' y está seguido por el md5 del session_id concatenado con la clave
# santerior key
$_SEC_SESSION['int']['filename']=$filename_sec="$sess_path/sec_sess_".md5(session_id().$md5);
if (isset($empty))
return 1;
if (!file_exists($filename_sec))
fclose(fopen($filename_sec,'w'));
if (!$_SEC_SESSION['int']['fd']=fopen($filename_sec,'r')){
$_SEC_SESSION['data']=serialize(array());
return 0;
}
# Los datos son desencriptados utilizando la clave key
if(filesize($filename_sec) > 0)
$data_enc=fread($_SEC_SESSION['int']['fd'],filesize($filename_sec));
fclose($_SEC_SESSION['int']['fd']);
if (isset($data_enc) && !empty($data_enc)){
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
mcrypt_generic_init($cipher, $_SEC_SESSION['int']['key'], INIT_VECTOR);
$data = mdecrypt_generic($cipher,$data_enc);
mcrypt_generic_deinit($cipher);
}
else
$data='';
$_SEC_SESSION['data']=$data;
$_SEC_SESSION['int']['hash']=md5($_SEC_SESSION['data']);
return 1;
}
function sess_close(){
return true;
}
function sess_read($key){
return $GLOBALS['_SEC_SESSION']['data'];
}
function sess_write($id,$data){
global $_SEC_SESSION;
$sd=$data;
if ($_SEC_SESSION['int']['hash'] != md5($sd)){
$fd=fopen($_SEC_SESSION['int']['filename'],'w');
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
mcrypt_generic_init($cipher, $_SEC_SESSION['int']['key'], INIT_VECTOR);
$data = mcrypt_generic($cipher,$sd);
mcrypt_generic_deinit($cipher);
fputs($fd,$data);
fclose($fd);
chmod($_SEC_SESSION['int']['filename'],0600);
}
}
function sess_destroy($key){
return(@unlink($GLOBALS['_SEC_SESSION']['int']['filename']));
}
// Importante dejar esta función vacia
function sess_gc($maxlifetime){}
// la siguiente función es para evitar poner todo esto en cada página que necesitemos crear
un session_start() ahora solo es necesario incluir con include_once este archivo con las funciones e inicializamos la sesión con sess_create.
function sess_create(){
// por defecto en php el save_handler esta en files, debemos cambiarlo a user para poder gestionar nosotros mismos las funciones de sesión
ini_set("session.save_handler", "user");
// con este asociamos las funciones por defecto de php del control de sesiones con las nuestras, ver manual de esta función para detalles
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
session_start();
}
Comentarios