Mcrypt Rijndael-128 to Openssl Aes-128-Ecb Conversion

MCrypt rijndael-128 to OpenSSL aes-128-ecb conversion

In your specific example I've found that by changing aes-128-ecb to aes-256-ecb, it produces the same output as the legacy mcrypt_encrypt.

Convert mcrypt_generic to openssl_encrypt

Mcrypts: MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC

is equivalent to:

OPENSSL: AES-256-CBC

I have no idea why there's the difference, but changing the 128 to 256 solved it for me.

Migrate PHP AES encryption from mcrypt to openssl return different encrypted string

Both codes use different AES variants and paddings. The mcrypt code applies AES-128 and Zero padding, the openssl code AES-256 and PKCS7 padding. To make sure that both ciphertexts match, both codes must use the same AES variant and padding.

mcrypt identifies the AES variant from the key size. Since $key is a 16 bytes key, AES-128 is used. openssl determines the AES variant based on the specification passed in the 2nd parameter. Keys that are too short are padded with 0 values to the required length, keys that are too long are truncated. Here, AES-256-CBC is specified, i. e. AES-256 is used. The 16 bytes key $key is therefore padded with 0 values and extended to a size of 32 bytes.

mcrypt implicitly uses Zero padding for encryption, which is not implicitly removed during decryption. PKCS7 padding is not supported. openssl implicitly applies PKCS7 padding for encryption, which is implicitly removed during decryption. Zero padding is not supported. If the openssl code should use Zero padding or the mcyrpt code PKCS7 padding, this must be implemented by yourself.

With regard to the migration from mcrypt to openssl, the openssl code is modified in the following to be functionally identical to the mcrypt code, i.e. AES-128 and Zero padding is used. With regard to the AES variant, only the specification AES-256-CBC must be changed to AES-128-CBC. Concerning padding, the default PKCS7 padding must be disabled using OPENSSL_ZERO_PADDING and Zero padding itself must be implemented (note that the OPENSSL_ZERO_PADDING flag only disables padding, but does not enable Zero padding; the name is badly chosen):

<?php
$str = "test";
$key = 'o6xSYYAVl2eapPI2';
$iv = 'fedcba9876543210';

function encrypt_openssl($str = NULL, $key, $iv) {

$encrypted = openssl_encrypt(
zeroPad($str, 16), // Zero pad plaintext
'AES-128-CBC', // Choose AES-128
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, // Disable PKCS7 Padding
$iv);

return bin2hex(@$encrypted);
}

function zeroPad($text, $bs) {
$pad = $bs - strlen($text) % $bs;
return ($pad < 16) ? $text . str_repeat("\0", $pad) : $text;
}

echo 'Openssl:'.encrypt_openssl($str,$key,$iv); // Openssl:57c86f3089535b3acfbe65cecbb662b9

For a comparison with your result, note that you have confused the labels of the outputs, i.e. the openssl result is labeled Mcrypt and vice versa!

A final note: In general, PKCS7 padding is more reliable than Zero padding, as the former contains the information of the padding length. This is not the case with Zero padding, so when removing the padding (i.e. after decryption) it is not possible to distinguish between regular and padding bytes. There are also different Zero padding variants, e.g. one does not pad if the length of the plaintext already corresponds to an integer multiple of the blocksize (this variant uses mcrypt), the other one pads with a complete block in this case.

openssl_encrypt VS mcrypt_encrypt

Two problems:

  1. You aren't Base64 decoding the key, so you're passing a 24-byte (= 192-bit) key to both openssl_encrypt and mcrypt_encrypt. Apparently, these functions interpret such a key in different ways! base64_decode the key first for consistent results.

    Alternatively, if you really want to use the Base64-encoded string as a 192-bit key, pass 'aes-192-cbc' as the method to openssl_encrypt(). This is what mcrypt is doing here. (Which is not the same as what would happen if you passed MCRYPT_RIJNDAEL_192 as the cipher -- that changes the block size, not the key size!)

  2. openssl_encrypt uses PKCS5 padding automatically. Padding the data before passing it to this function ends up making the data get padded twice, leaving it one block longer than intended.

With these problems fixed, both functions now give the same result.

MCrypt rijndael-256 to OpenSSL aes-256-ecb conversion

Saddly, you are on the wrong way.

Refer to :

http://php.net/manual/en/function.mcrypt-encrypt.php#117667

MCRYPT_RIJNDAEL_256 is not AES-256, it's a different variant of the
Rijndael block cipher.

https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

AES is a variant of Rijndael which has a fixed block size of 128 bits,
and a key size of 128, 192, or 256 bits. By contrast, the Rijndael
specification per se is specified with block and key sizes that may be
any multiple of 32 bits, with a minimum of 128 and a maximum of 256
bits.

So you can not use OpenSSL's AES-256 to decrypt the MCrypt's output.

Some possible methods:

  1. Keep using mcrypt by PECL's mcrypt extension (luckily, it is still there), until you can replace the legacy data totally.

  2. Rewrite a correct RIJNDAEL-256 cipher in PHP.



Related Topics



Leave a reply



Submit