Last active
August 29, 2015 14:07
-
-
Save steelywing/121d7b9c0b56a3334000 to your computer and use it in GitHub Desktop.
php mcrypt class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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