Replacing mcrypt_encrypt using MCRYPT_RIJNDAEL_256 with openssl_encrypt

mcrypt_rijndael_128 openssl
mcrypt_rijndael_128 aes 256 cbc
deprecated function mcrypt_encrypt
php mcrypt_encrypt replacement
mcrypt_generic_init alternative
mcrypt_get_block_size mcrypt_rijndael_128 cbc
mcrypt to openssl

As you guys probably know, the extension mcrypt will be deprecated on php 7.1.

I use to maintain a "legacy" application that I want to migrate eventually to this version so I ran the tests and verified that I can't get 100% of coverage anymore, since there's a piece of code that use the following code:

$key = 'sA*(DH';

// initialization vector
$iv = md5(md5($key));
$output = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string,     MCRYPT_MODE_CBC, $iv));

I tried to port this piece of code to openssl_encrypt using this code

$key = md5('sA*(DH');
$iv = md5($key);
echo base64_encode(openssl_encrypt($data, "aes-256-cbc", $key, OPENSSL_RAW_DATA, $iv));

But I have 2 problems with this:

  1. The IV lenght should be 16 chars (and md5 gives me 32), so I get a PHP Warning
  2. The output it's not the same (even if I truncate to 16 chars)

Anyone had similar problems (or know how to fix it?)

BTW: I'm using the dev master version of PHP (supposed to be 7.1.0 alpha 3).

You should really get out of the habit of using md5 for anything.

$iv = openssl_random_pseudo_bytes(16);
$key = substr(hash('sha256', 'sA*(DH'), 0, 32)

mcrypt_encrypt and openssl_encrypt will not output the same crypttext given the same plaintext and key.

also, mcrypt is deprecated in PHP 7.1, not you can update to 7.1 without changing from mcrypt to openssl ... but it is a good idea to remove mcrypt in general.

mcrypt is deprecated, what is the alternative?, As suggested by @rqLizard, you can use openssl_encrypt / openssl_decrypt PHP Also, MCRYPT_RIJNDAEL_256 is not AES-256 , it's a different variant of the Rijndael block cipher. $encrypt = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $key, $session_id, Another issue, you don't need replacement any code. In my case I used Blowfish in ECB mode. The task was to decrypt data with openssl_decrypt, encrypted by mcrypt_encrypt and vice versa. It was obvious for a first sight. But in fact openssl_encrypt and mcrypt_encript give different results in most cases. Investigating the web I found out that the reason is in different padding methods.

Yet another tested solution taking and returning ANSI text to replace Mcrypt function with the openssl_encrypt() and openssl_decrypt():

//Return encrypted string
public function stringEncrypt ($plainText, $cryptKey = '7R7zX2Urc7qvjhkr') {

  $cipher   = 'aes-128-cbc';

  if (in_array($cipher, openssl_get_cipher_methods()))
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext_raw = openssl_encrypt(
      $plainText, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext_raw, $cryptKey, $as_binary=true);
    $encodedText = base64_encode( $iv.$hmac.$ciphertext_raw );

  return $encodedText;

//Return decrypted string
public function stringDecrypt ($encodedText, $cryptKey = '7R7zX2Urc7qvjhkr') {

  $c = base64_decode($encodedText);
  $cipher   = 'aes-128-cbc';

  if (in_array($cipher, openssl_get_cipher_methods()))
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = substr($c, 0, $ivlen);
    $hmac = substr($c, $ivlen, $sha2len=32);
    $ivlenSha2len = $ivlen+$sha2len;
    $ciphertext_raw = substr($c, $ivlen+$sha2len);
    $plainText = openssl_decrypt(
      $ciphertext_raw, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);

  return $plainText;

More read in openssl documentation

Don't use mcrypt, You should use libsodium if you can, or OpenSSL if you can't. $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plaintext, openssl_encrypt() performs PKCS7 padding by default, and lets you specify� I have the following code which worked fine on PHP 5.5.9. function index() { echo $this->encryptText_3des('TEST','JHHKJH9879'); } function encryptText_3des($plainText

There are 2 problems :

  1. MCrypt uses zero padding while Openssl uses by default PKCS#7
  2. Openssl needs the input string to be of proper length (multiple of block length)

To solve this problems :

  1. add OPENSSL_ZERO_PADDING flag to openssl_encrypt/openssl_decrypt
  2. if input string length is not multiple of block length then append to the input string zero chars "\0" [aka chr(0)];

That being said this should solve the problem:

// key/iv in ASCII binary data, $str base64
function decrypt_stuff($key, $str, $iv) {
    // $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($str), MCRYPT_MODE_CBC, $iv);
    $plaintext_dec = openssl_decrypt(base64_decode($str), "aes-256-cbc", $key,  OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
    return $plaintext_dec;

// key/iv in ascii binary data, $str ascii
function encrypt_stuff($key, $str, $iv) {
    // $ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC, $iv));
    if (($l = (strlen($str) & 15)) > 0) { $str .= str_repeat(chr(0), 16 - $l); }
    $ciphertext = base64_encode(openssl_encrypt($str, "aes-256-cbc", $key,  OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv));
    return $ciphertext;

Solution to the problem that the mcrypt extension of php has been , php's mcrypt UU function cluster started deprecated in version 7.1.0 and was It is officially recommended to replace mcrypt and mcrypt with OpenSSL Mcrypt? Rijndael? 256 is not AES-256. MCRYPT_RIJNDAEL_128 & CBC + 16 position Key = openssl_encrypt(AES-128-CBC, 16 position Key)� I am currently in the process of replacing Mcrypt with OpenSSL since Mcrypt will be deprecated in PHP 7.1. I need is a way to get the blocksize per algorithm like mcrypt_get_block_size(). I am wondering if there is an equivalent function to mcrypt_ge

Use openssl_encrypt to replace Mcrypt for 3DES-ECB encryption, "\n"; $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv); file_put_contents('path/to/your/file', $crypttext); ?> It encrypts� Base64 encoding works by replacing groups of three binary bytes (3 x 8 = 24 bits) with four ASCII-6 characters (4 x 6 = 24 bits). This means that the input text must have a length multiple of three and the output will always have a length multiple of four.

mcrypt_encrypt - Manual, show key size use either 16, 24 or 32 byte keys for AES-128, 192 If you're writing code to encrypt/encrypt data in 2015, you should use openssl_encrypt() and Also, MCRYPT_RIJNDAEL_256 is not AES-256, it's a different variant of the� First of all. I'm on thin ice here! I have a encrypted file that I get from php. I'm trying to decrypt this with golang. The php application uses a public RSA key to encrypt the key used to encrypt with aes-256-cbc.

mcrypt is deprecated, what is the alternative?, How to check if mcrypt extension exists in php, Replace mcrypt_encrypt with openssl_encrypt $encrypted = bin2hex(mcrypt_encrypt( MCRYPT_RIJNDAEL_128,� Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.