Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

[Resolvido] Dados criptografados na sessão PHP

Recommended Posts

Neste artigo, apresento um exemplo de forte criptografia em PHP para dadosem uma sessão segura. Essa é uma simplesimplementação que pode ser usada para melhorar a segurança de aplicações PHP,especialmente em ambientes compartilhados nos quais usuários diferentes têm acessoaos mesmos recursos. Como você sabe, os dados nas sessões PHP são gerenciadospor padrão usando arquivos temporários. Em um ambiente compartilhado, umusuário malicioso que é capaz de acessar esses arquivos temporários podefacilmente ler esses dados porque eles estão armazenados em plaintext (dados emum arquivo de sessão é a serialização do array $_SESSION).

Em teoria, os dados na sessão deveriamser armazenados em pastas que somente são acessíveis pelo dono do website, masnunca diga nunca (falando nisso, você pode gerenciar o local dos dados nasessão usando a função session_save_path ou mudando a session_save_path nophp.ini).

Para assegurar aos dados na sessão, eu usei uma criptografia forte para criptografar o conteúdousando a extensão mcrypt do PHP. Eu escolhei a cifra simétrica Rijandel-256 para criptografar osdados da sessão e a função openssl_random_pseudo_bytes() para gerar umachave randômica de 256 bit.

A ideia é usar umcookie variável para armazenar a chave que será usada para criptografar osdados na sessão. Dessa maneira, a chave é armazenada somente no cliente (obrowser) e somente o cliente é capaz de descriptografar os dados da sessão noservidor. Cada vez que criptografamos os dados da sessão, nós geramos mais umavez o vetor IV de maneira randômica usando a função mcrypt_create_iv(). É muito importante gerar um único IV em cada criptografia. Essa práticaotimizada melhora a segurança do algoritmo criptografado.

É importante notarque essa implementação não é segura contra um ataque de hijacking. Se outra pessoa for capaz de capturar ocookie variável de um cliente e tiver acesso aos arquivos temporários dassessões, dentro do servidor, ele ou ela será capaz de descriptografar os dadosda sessão. Nosso objetivo éproteger os dados da sessão contra ataques em ambientes compartilhados.

A ideia decriptografar os dados na sessão não é nova, por exemplo, Chris Shiflett propôs uma implementação em seu livro ?Essential PHP Security? (O?Reilly, 2006). Shiflett usou uma variável $_SERVER paraarmazenar a chave usada para criptografar os dados da sessão. Kevin Schroeder, meu colega na Zend Technologies, implementou um algoritimo decriptografia de sessão muito similar estendendo a classe Zend_Session do Zend Framework (você pode encontrá-lo aqui). Na minha solução, euusei algumas das melhores práticas relacionadas a fortes criptografias paraimplementar um handler seguro de sessões.

Abaixoestá o código-fonte da minha implementação:

/**

* ------------------------------------------------

* Encrypt PHP session data using files

* ------------------------------------------------

* The encryption is built using mcrypt extension

* and the randomness is managed by openssl

*

* @author Enrico Zimuel (enrico@zimuel.it)

* @copyright GNU General Public License

*/

class SecureSession {

const CIPHER= MCRYPT_RIJNDAEL_256;

const CIPHER_MODE= MCRYPT_MODE_CBC;

/**

* Key for encryption/decryption

*

* @var string

*/

private static $_key;

/**

* Path of the session file

*

* @var string

*/

private static $_path;

/**

* Session name (optional)

*

* @var string

*/

private static $_name;

/**

* Size of the IV vector for encryption

*

* @var integer

*/

private static $_ivSize;

/**

* Cookie variable name of the key

*

* @var string

*/

private static $_keyName;

/**

* Generate a random key

* fallback to mt_rand if PHP < 5.3 or no openssl available

*

* @param integer $length

* @return string

*/

private static function _randomKey($length=32) {

if(function_exists('openssl_random_pseudo_bytes')) {

$rnd = openssl_random_pseudo_bytes($length, $strong);

if($strong === TRUE)

return $rnd;

}

for ($i=0;$i<$length;$i++) {

$sha= sha1(mt_rand());

$char= mt_rand(0,30);

$rnd.= chr(hexdec($sha[$char].$sha[$char+1]));

}

return $rnd;

}

/**

* Open the session

*

* @param string $save_path

* @param string $session_name

* @return bool

*/

public static function open($save_path, $session_name) {

self::$_path= $save_path.'/';

self::$_name= $session_name;

self::$_keyName= "KEY_$session_name";

self::$_ivSize= mcrypt_get_iv_size(self::CIPHER, self::CIPHER_MODE);

 

if (empty($_COOKIE[self::$_keyName])) {

$keyLength= mcrypt_get_key_size(self::CIPHER, self::CIPHER_MODE);

self::$_key= self::_randomKey($keyLength);

$cookie_param = session_get_cookie_params();

setcookie(

self::$_keyName,

base64_encode(self::$_key),

$cookie_param['lifetime'],

$cookie_param['path'],

$cookie_param['domain'],

$cookie_param['secure'],

$cookie_param['httponly']

);

} else {

self::$_key= base64_decode($_COOKIE[self::$_keyName]);

}

return true;

}

/**

* Close the session

*

* @return bool

*/

public static function close() {

return true;

}

/**

* Read and decrypt the session

*

* @param integer $id

* @return string

*/

public static function read($id) {

$sess_file = self::$_path.self::$_name."_$id";

$data= @file_get_contents($sess_file);

if (empty($data)) {

return false;

}

$iv= substr($data,0,self::$_ivSize);

$encrypted= substr($data,self::$_ivSize);

$decrypt = mcrypt_decrypt(

self::CIPHER,

self::$_key,

$encrypted,

self::CIPHER_MODE,

$iv

);

return rtrim($decrypt, "?");

}

/**

* Encrypt and write the session

*

* @param integer $id

* @param string $data

* @return bool

*/

public static function write($id, $data) {

$sess_file = self::$_path.self::$_name."_$id";

$iv= mcrypt_create_iv(self::$_ivSize, MCRYPT_RAND);

if ($fp = @fopen($sess_file, "w")) {

$encrypted= mcrypt_encrypt(

self::CIPHER,

self::$_key,

$data,

self::CIPHER_MODE,

$iv

);

$return = fwrite($fp, $iv.$encrypted);

fclose($fp);

return $return;

} else {

return false;

}

}

/**

* Destroy the session

*

* @param int $id

* @return bool

*/

public static function destroy($id) {

$sess_file = self::$_path.self::$_name."_$id";

setcookie (self::$_keyName, '', time() - 3600);

return(@unlink($sess_file));

}

/**

* Garbage Collector

*

* @param int $max

* @return bool

*/

public static function gc($max) {

foreach (glob(self::$_path.self::$_name.'_*') as $filename) {

if (filemtime($filename) + $max < time()) {

@unlink($filename);

}

}

return true;

}

}

// Set the custom PHP session handler

ini_set('session.save_handler', 'user');

session_set_save_handler(array('SecureSession', 'open'),

array('SecureSession', 'close'),

array('SecureSession', 'read'),

array('SecureSession', 'write'),

array('SecureSession', 'destroy'),

array('SecureSession', 'gc')

);

Você pode fazer odownload da classe SecureSession aqui.

Para poder usar aclasse SecureSession, você tem que incluí-la no seu projeto PHP antes da funçãosession_start.

Depois disso, você pode usar a sessão PHP da maneiranormal.

?

Texto original disponível em http://www.zimuel.it/en/encrypt-php-session-data/

 

http://imasters.com.br/artigo/22252/php/dados-criptografados-na-sessao-php

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.