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

Solution 1:

Here is what worked for me:

<?php

$str = 'Content';
if (strlen($str) % 16) {
    $str = str_pad($str, strlen($str) + 16 - strlen($str) % 16, "\0");
}

$key = 'KEY';
if (strlen($key) % 16) {
    $key = str_pad($key, strlen($key) + 16 - strlen($key) % 16, "\0");
}

$res1 = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
echo strToHex($res1) . ' | mcrypt_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res1, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';

echo "<hr>";

$res2 = openssl_encrypt($str, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
echo strToHex($res2) . ' | openssl_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res2, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';


function strToHex($string) {
    $hex = '';
    for ($i = 0; $i < strlen($string); $i++) {
        $ord     = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex     .= substr('0' . $hexCode, -2);
    }

    return strToUpper($hex);
}

Solution 2:

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.

Solution 3:

Most likely the key was expected to be used as hex (it already is in hex format) not as a string to be converted to hex.


mcrypt:

mcrypt does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding but the padding is being explicitly added prior to mcrypt.

The encryption v7IXp5vVaFVXXlt/MN8BVw== is the correct encryption based on PKCS#7 padding. ECB mode and the key as a string.

See: mcrypt - AES CALCULATOR.

In hex, notice the data padding is clearly visible:
key: 6130613765373939376236643566636435356634623563333236313162383763
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: BFB217A79BD56855575E5B7F30DF0157

In Base64:
encrypted: v7IXp5vVaFVXXlt/MN8BVw==


OpenSSL:

Notice the key is 256-bits but the OpenSSL call with "aes-128-ecb" seems to imply a 128-but key. So the keys don't match.

See: OpenSSL - AES CALCULATOR

In hex, notice the data padding is clearly visible:
key: 61306137653739393762366435666364
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: 4B1277F8475A788B59C77FC4C064D46F

In Base64:
encrypted: SxJ3+EdaeItZx3/EwGTUbw==