2awm366 2awm366 - 8 months ago 48
PHP Question

PHP MCrypt decryption fails unless using AES-256

I have written a class to encrypt and decrypt strings, but I can't use any cipher except

. The program always report that the message is corrupted. How can I fix it?

The ciphers I have tested which fails are

Here's my code:

class Crypt {
private $masterKey;
private $subKey;
private $cipher = MCRYPT_RIJNDAEL_256 ;
private $cipherMode = MCRYPT_MODE_CFB;
//private $hashAlog = 'sha256';

public function __construct($masterKey) {
$this->masterKey = $masterKey;

public function setKey($masterKey) {

public function encrypt($message) {
$iv = mcrypt_create_iv($this->getIVSize());
$hmac = $this->signMsg($message);
$cipherText = mcrypt_encrypt($this->cipher, $this->subKey, $message, $this->cipherMode, $iv);
$cipherText = $iv . $hmac . $cipherText;
return base64_encode($cipherText);

public function decrypt($enc_message) {
$mixedMsg = base64_decode($enc_message);
$iv = substr($mixedMsg, 0, $this->getIVSize());
$hmac = substr($mixedMsg, $this->getIVSize(), strlen($this->signMsg(null)));
$cipherText = substr($mixedMsg, $this->getIVSize() + strlen($this->signMsg(null)));
$message = mcrypt_decrypt($this->cipher, $this->subKey, $cipherText, $this->cipherMode, $iv);
die("Decrypt Error!");
if($hmac != $this->signMsg($message))
die("Message Corrupted");
return $message;

private function genSubKey($iv) {
$this->subKey = hash_pbkdf2("sha256", $this->masterKey, $iv, 50000, $this->getKeySize());

private function getKeySize() {
return mcrypt_get_key_size($this->cipher, $this->cipherMode);

private function getIVSize() {
return mcrypt_get_iv_size($this->cipher, $this->cipherMode);

private function signMsg($message) {
return hash_hmac("sha512", $message, $this->masterKey, true);


The problem is caused by the hash_pbkdf2 function in the genSubKey function. Since hash_pbkdf2 will output hex encoded strings, it will be twice as long as the key size. To solve this, we need to pass true as an additional parameter to it, let it output raw bytes and fit the key size.

Here's the corrected code:

private function genSubKey($iv) {
    $this->subKey = hash_pbkdf2("sha256", $this->masterKey, $iv, 50000, $this->getKeySize(), true);