1

We are upgrading a platform from PHP 5.6 to PHP 7.4 where MCRYPT has been removed.

We have many clients that have URLs that include mcrypt encrypted codes that we need to be able to decrypt using PHP 7.4 compatible code as not to break existing functionality. I have not been able to find an equivalent decryption process to solve this issue.

Here is the PHP 5.6 code for encrypting and decrypting the data:

function encrypt($string, $encryption_key) {
    return mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($string), MCRYPT_MODE_ECB);
}
function decrypt($encrypted_string, $encryption_key) {
    return mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB);
}

This is being used to produce the necessary query string parameter:

define("ENCRYPTION_KEY", "_enc_key");
$example_string = "My_String|2|Encode";
$enc_url_param = urlencode(base64_encode(encrypt($example_string, ENCRYPTION_KEY)));

This is what is taking place to decrypt the QS param:

$decrypted = trim(decrypt(base64_decode($_GET['enc_param']), ENCRYPTION_KEY));
// trimming is required due to trailing empty characters

Some more background:

  • In the PHP 5.6 version, new querystring parameters were being generated with every retrieval, so I cannot predict all the code variations that are out there.
  • This encryption is only used to obfuscate IDs in a sharable URL and there are other measures in place to ensure security is maintained.
matteo
  • 71
  • 7
  • Use OpenSSL with `bf-ecb` as the cipher. Also stop using `utf8_encode()`. At best, and most likely, it is doing _nothing_, and at worst it is corrupting your data. – Sammitch Jul 18 '22 at 18:53
  • @Sammitch That does not yield to correct results. – matteo Jul 18 '22 at 19:59

1 Answers1

0

I found the answer here: https://stackoverflow.com/a/54190706/9178609

Previously I had tried using OpenSSL with bf-ecb as the cipher (also recommended in the comments by @Sammitch), but the results were failing due to the necessity for the undocumented OPENSSL_DONT_ZERO_PAD_KEY

This is the code that works:

$decrypted = openssl_decrypt(base64_decode($_GET['enc_param']), 'bf-ecb', ENCRYPTION_KEY, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING | OPENSSL_DONT_ZERO_PAD_KEY);

It's also worth noting that PHP 5.6 does not provide the same results as running this code in PHP 7.4.

matteo
  • 71
  • 7
  • You should also make sure that cipher is available. I think on newer versions of `openssl` the `BF-ECB` cipher is not available by default, so you would need to enable legacy ciphers. https://stackoverflow.com/questions/73066462/apache-php-installing-cypher-for-openssl-missed-in-openssl-get-cipher-method – fred Feb 02 '23 at 17:17