Skip to content

Instantly share code, notes, and snippets.

@spiechu
Created April 5, 2012 08:38
Show Gist options
  • Save spiechu/2309214 to your computer and use it in GitHub Desktop.
Save spiechu/2309214 to your computer and use it in GitHub Desktop.
Class designed to encrypt and decrypt cookies along with some unit tests.
<?php
class SpiechuCookieEncrypter
{
const SEPARATOR = '(sep)';
protected $password = null;
protected $algorithm = null;
protected $mode = null;
public function __construct()
{
}
public function setPassword($pass)
{
$this->password = $pass;
return $this;
}
public function setAlgorithm($arg)
{
if ($this->checkMcryptList('algorithms', $arg)) {
$this->algorithm = $arg;
return $this;
} else {
throw new InvalidArgumentException('Nie znaleziono algorytmu!');
}
}
public function setMode($arg)
{
if ($this->checkMcryptList('modes', $arg)) {
$this->mode = $arg;
return $this;
} else {
throw new InvalidArgumentException('Nie znaleziono trybu!');
}
}
protected function checkMcryptList($list, $check)
{
$args = "mcrypt_list_$list";
$args = $args();
return in_array($check, $args) ? true : false;
}
protected function okToGo()
{
return ($this->algorithm === null
|| $this->mode === null
|| $this->password === null) ? false : true;
}
protected function getIV()
{
return mcrypt_create_iv($this->getIVSize());
}
protected function getIVSize()
{
return mcrypt_get_iv_size($this->algorithm, $this->mode);
}
protected function encrypt($value, $iv)
{
return trim(mcrypt_encrypt($this->algorithm, $this->password, $value, $this->mode, $iv));
}
protected function decrypt($value, $iv)
{
return trim(mcrypt_decrypt($this->algorithm, $this->password, $value, $this->mode, $iv));
}
protected function getEncryptedString($string)
{
$iv = $this->getIV();
return base64_encode($this->encrypt($string, $iv) . self::SEPARATOR . $iv);
}
protected function parseEncryptedString($string)
{
$string = base64_decode($string, TRUE);
if ($string === FALSE) {
throw new InvalidArgumentException('Ciag poza alfabetem base64');
} else {
$string = explode(self::SEPARATOR, $string, 2);
if (!isset($string[0]) || !isset($string[1]) || $string[0] == '' || $string[1] == '') {
throw new InvalidArgumentException('Ciag jest uszkodzony');
} else {
return $this->decrypt($string[0], $string[1]);
}
}
}
public function setEncryptedCookie($name, $value, $expire = 0)
{
if ($this->okToGo()) {
return setcookie($name, $this->getEncryptedString($value), $expire, '/');
} else
return false;
}
public function getEncryptedCookie($name)
{
if ($this->okToGo()) {
if (isset($_COOKIE[$name])) {
return $this->parseEncryptedString($_COOKIE[$name]);
} else {
return null;
}
} else
return false;
}
}
<?php
require_once 'PHPUnit/Framework.php';
require_once dirname(__FILE__) . '/../../SpiechuCookieEncrypter.php';
class SpiechuCookieEncrypterTest extends PHPUnit_Framework_TestCase
{
protected $cookieEncrypter;
const TESTED_ALGORITHM = 'rijndael-128';
const TESTED_IV_SIZE = 16;
const TESTED_MODE = 'cbc';
const TESTED_VALUE = 'lubisz mnie ?';
const TESTED_PASSWORD = 'jakies haslo';
const TESTED_COOKIE_NAME = 'cookie_name';
const TESTED_COOKIE_VALUE = 'cookie_value';
protected function setUp()
{
$this->cookieEncrypter = new PublicSpiechuCookieEncrypter();
}
protected function tearDown()
{
}
public function testSeparator()
{
$this->assertEquals(SpiechuCookieEncrypter::SEPARATOR, '(sep)');
}
public function testSetPassword()
{
$this->cookieEncrypter->setPassword(self::TESTED_PASSWORD);
$this->assertEquals($this->cookieEncrypter->get('password'), self::TESTED_PASSWORD, 'Pole klasy powinno miec wartosc ' . self::TESTED_PASSWORD);
}
public function testCheckMcryptList()
{
$this->assertTrue($this->cookieEncrypter->publicCheckMcryptList('algorithms', self::TESTED_ALGORITHM), 'Powinien znalezc algorytm ' . self::TESTED_ALGORITHM);
$this->assertFalse($this->cookieEncrypter->publicCheckMcryptList('algorithms', 'dummy'), 'Nie powinien znalezc algorytmu dummy');
$this->assertTrue($this->cookieEncrypter->publicCheckMcryptList('modes', self::TESTED_MODE), 'Powinien znalezc tryb ' . self::TESTED_MODE);
$this->assertFalse($this->cookieEncrypter->publicCheckMcryptList('modes', 'dummy'), 'Nie powinien znalezc trybu dummy');
}
public function testSetAlgorithmWillThrowException()
{
$this->setExpectedException('InvalidArgumentException');
$this->cookieEncrypter->setAlgorithm('dummy');
}
public function testSetAlgorithm()
{
$this->cookieEncrypter->setAlgorithm(self::TESTED_ALGORITHM);
$this->assertEquals($this->cookieEncrypter->get('algorithm'), self::TESTED_ALGORITHM, 'Powinien zwrocic ' . self::TESTED_ALGORITHM);
}
public function testSetModeWillThrowException()
{
$this->setExpectedException('InvalidArgumentException');
$this->cookieEncrypter->setMode('dummy');
}
public function testSetMode()
{
$this->cookieEncrypter->setMode(self::TESTED_MODE);
$this->assertEquals($this->cookieEncrypter->get('mode'), self::TESTED_MODE, 'Powinien zwrocic ' . self::TESTED_MODE);
}
public function testOkToGo()
{
$this->assertFalse($this->cookieEncrypter->publicOkToGo());
$this->cookieEncrypter->setAlgorithm(self::TESTED_ALGORITHM);
$this->assertFalse($this->cookieEncrypter->publicOkToGo());
$this->cookieEncrypter->setMode(self::TESTED_MODE);
$this->assertFalse($this->cookieEncrypter->publicOkToGo());
$this->cookieEncrypter->setPassword(self::TESTED_PASSWORD);
$this->assertTrue($this->cookieEncrypter->publicOkToGo());
}
public function testGetIVSize()
{
$this->cookieEncrypter->setAlgorithm(self::TESTED_ALGORITHM);
$this->cookieEncrypter->setMode(self::TESTED_MODE);
$size = $this->cookieEncrypter->publicGetIVSize();
$this->assertEquals($size, self::TESTED_IV_SIZE, 'Wielkosc wektora powinna wynosic ' . self::TESTED_IV_SIZE);
}
public function testGetIV()
{
$this->cookieEncrypter->setAlgorithm(self::TESTED_ALGORITHM);
$this->cookieEncrypter->setMode(self::TESTED_MODE);
$this->assertNotNull($this->cookieEncrypter->publicGetIV());
}
protected function standardPrepareEncrypter()
{
$this->cookieEncrypter->setAlgorithm(self::TESTED_ALGORITHM);
$this->cookieEncrypter->setMode(self::TESTED_MODE);
$this->cookieEncrypter->setPassword(self::TESTED_PASSWORD);
}
public function testEncryptDecrypt()
{
$this->standardPrepareEncrypter();
$iv = $this->cookieEncrypter->publicGetIV();
$encrypted = $this->cookieEncrypter->publicEncrypt(self::TESTED_VALUE, $iv);
$this->assertEquals($this->cookieEncrypter->publicDecrypt($encrypted, $iv), self::TESTED_VALUE);
}
/**
* @depends testEncryptDecrypt
*/
public function testEncryptedString()
{
$this->standardPrepareEncrypter();
$encrypted = $this->cookieEncrypter->publicGetEncryptedString(self::TESTED_COOKIE_VALUE);
$this->assertEquals($this->cookieEncrypter->publicParseEncryptedString($encrypted), self::TESTED_COOKIE_VALUE);
}
/**
* @dataProvider malformedStringProvider
*/
public function testMalformedStringReactions($string)
{
$this->standardPrepareEncrypter();
$this->setExpectedException('InvalidArgumentException');
$this->cookieEncrypter->publicParseEncryptedString($string);
}
public function malformedStringProvider()
{
return array(
array(
'i\'m malformed string'
),
array(
'@#$#@$#@'
),
array(
''
),
array(
'd(-_-)b'
),
array(
'sam tekst'
),
array(
'012345'
),
array(
'DFGFDGSDFfsdfsd%$%$%$'
),
array(
'%$#%$&%^*&^^#$SRGDFHDB gdfbg543 534534 '
)
);
}
}
class PublicSpiechuCookieEncrypter extends SpiechuCookieEncrypter
{
public function publicCheckMcryptList($list, $check)
{
return $this->checkMcryptList($list, $check);
}
public function publicGetIVSize()
{
return $this->getIVSize();
}
public function publicGetIV()
{
return $this->getIV();
}
public function get($field)
{
$field = "{$this->$field}";
return $field;
}
public function publicEncrypt($value, $iv)
{
return $this->encrypt($value, $iv);
}
public function publicDecrypt($value, $iv)
{
return $this->decrypt($value, $iv);
}
public function publicGetEncryptedString($string)
{
return $this->getEncryptedString($string);
}
public function publicParseEncryptedString($string)
{
return $this->parseEncryptedString($string);
}
public function publicOkToGo()
{
return $this->okToGo();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment