Skip to content

Instantly share code, notes, and snippets.

@steelywing
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steelywing/121d7b9c0b56a3334000 to your computer and use it in GitHub Desktop.
Save steelywing/121d7b9c0b56a3334000 to your computer and use it in GitHub Desktop.
php mcrypt class
<?php
include_once 'Mcrypt.php';
$data = 'Encryption testing data';
$mcrypt = new Mcrypt('password');
$encrypted = $mcrypt->encrypt($data);
echo 'Encrypted data: ' . base64_encode($encrypted) . "\n";
echo 'Decrypted data: ' . $mcrypt->decrypt($encrypted) . "\n";
<?php
class Mcrypt
{
/**
* @var string Encryption key
*/
public $key;
/**
* @var string mcrypt mode
*/
protected $mode;
/**
* @var resource mcrypt cipher
*/
protected $cipher;
/**
* @param string $key
*/
public function __construct($key = '', $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC)
{
if (!mcrypt_get_cipher_name($cipher)) {
throw new \InvalidArgumentException('Unsupport mcrypt cipher: ' . $cipher);
}
if (!in_array($mode, mcrypt_list_modes())) {
throw new \InvalidArgumentException('Unsupport mcrypt mode: ' . $mode);
}
$this->cipher = $cipher;
$this->mode = $mode;
$this->key = $key;
}
/**
* @param $data
* @return string
*/
public function encrypt($data)
{
$ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
$iv = mcrypt_create_iv($ivSize);
$key = substr(
mhash(MHASH_SHA256, $this->key),
0,
mcrypt_get_key_size($this->cipher, $this->mode)
);
$encrypted = mcrypt_encrypt(
$this->cipher,
$key,
$this->pad($data),
$this->mode,
$iv
);
return $iv . $encrypted;
}
/**
* @param $data
* @return string
*/
public function decrypt($data)
{
$ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
if (strlen($data) < $ivSize + 1) {
throw new \InvalidArgumentException('Decryption data error');
}
$iv = substr($data, 0, $ivSize);
$key = substr(
mhash(MHASH_SHA256, $this->key),
0,
mcrypt_get_key_size($this->cipher, $this->mode)
);
$decryptedData = mcrypt_decrypt(
$this->cipher,
$key,
substr($data, $ivSize),
$this->mode,
$iv
);
return $this->unpad($decryptedData);
}
private function pad($data)
{
$blockSize = mcrypt_get_block_size($this->cipher, $this->mode);
$pad = $blockSize - (strlen($data) % $blockSize);
return $data . str_repeat(chr($pad), $pad);
}
private function unpad($data)
{
$pad = ord($data[strlen($data) - 1]);
return substr($data, 0, -$pad);
}
}
<?php
include_once 'Mcrypt.php';
class McryptTest extends \PHPUnit_Framework_TestCase
{
public function testEncryptedMessageShouldNotBeEqualToSourceMessage()
{
$mcrypt = new Mcrypt('p@55w0rd');
$data = 'testing data';
$this->assertNotEquals($data, $mcrypt->encrypt($data));
}
/**
* @dataProvider inputDataProvider
*/
public function testEncryptionShouldNotChangeMessage($data)
{
$mcrypt = new Mcrypt('p@55w0rd');
$this->assertEquals(
$data,
$mcrypt->decrypt(
$mcrypt->encrypt($data)
)
);
}
public function inputDataProvider()
{
return array_map(
function ($item) {
return array($item);
}, array(
'testing data',
' testing data with spaces ',
"testing data
with
line break \0\0"
)
);
}
public function testEncryptedMessageIsDifferentForSameInputs()
{
$data = 'testing data';
$mcrypt = new Mcrypt('p@55w0rd');
$this->assertNotEquals(
$mcrypt->encrypt($data),
$mcrypt->encrypt($data)
);
}
public function testDecryptWithWrongKey()
{
$data = 'testing data';
$mcrypt = new Mcrypt('p@55w0rd');
$encryptedData = $mcrypt->encrypt($data);
$mcrypt->key = 'password';
$this->assertNotEquals(
$data,
$mcrypt->decrypt($encryptedData)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment