0

I was handed this code snippet as an example, and I'm trying to make it a little more "modern":

$key='09KzF2qMBy58ZWg137N$I4h6UwJvp!ij';
$encrypted='Chttex_vuYYEK-oKQfwYrVCZYbnNh3tMgwGuK-VOsvt7TjF5M6MIcsE6e8DynZrHuxrmtmIpiN215WygdO-hzXnmx45RXzBWdxk_MkIvNoI=';
$encrypted = urlsafe_b64decode($encrypted);
$decrypted = decrypt($encrypted, $key);
$inflated = gzinflate($decrypted);

echo 'Decrypted: '.$inflated."<br />";

function urlsafe_b64decode($data) {
  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

function decrypt($data, $key)
{
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);
}

I'm on PHP7 and trying to convert this use openssl. I take the string and run it through the existing 'urlsafe_b64decode' function, then created another 'decrypt' function:

function decrypt($string, $key)
{
    return openssl_decrypt($string, 'AES-256-ECB', $key);
}

I thought it would be a fairly simply 1-to-1 conversion, but its always returning "false". Any ideas what I might be doing wrong? Thanks in advance!

edit : Since the service I'm using is a .NET shop, here's their example for .NET for encrypting, if it helps at all.

Public Shared Function Encrypt(ByVal data As Byte()) As Byte()
        Dim encrypted As Byte()

        Using rijAlg = New System.Security.Cryptography.AesManaged()
            rijAlg.Key = Encoding.ASCII.GetBytes("encryptionkeyhere")
            rijAlg.Padding = System.Security.Cryptography.PaddingMode.None
            rijAlg.Mode = System.Security.Cryptography.CipherMode.ECB
            Dim encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV)

            Using msEncrypt = New MemoryStream()
                Using csEncrypt = New System.Security.Cryptography.CryptoStream(msEncrypt, encryptor, System.Security.Cryptography.CryptoStreamMode.Write)
                    csEncrypt.Write(data, 0, data.Length)
                End Using

                encrypted = msEncrypt.ToArray()
            End Using
        End Using

        Return encrypted
End Function

update 2 So I updated my local server to have mcrypt, and was able to decode the encrypted string from my initial code snippet. This is the desired response: "sessionid=7bf727043d85e6963e640fb541d886a7454f8091&requestid=1488925528"

After googleing and stackoverflow-ing and experimenting, I'm still unable to decrypt the string correctly using openssl. Is it even possible?

TerryMatula
  • 1,264
  • 2
  • 14
  • 29
  • Why not simply decode your your string with Mcrypt and then re-encrypt it with OpenSSL? – Lucas Krupinski Mar 07 '17 at 22:52
  • Unfortunately, it's a PHP7 server and I don't have access to install the mcrypt extension, or change the ini file. – TerryMatula Mar 08 '17 at 00:59
  • Do not use ECB mode, it is insecure, see [ECB mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29), scroll down to the Penguin. Instead use CBC mode with a random IV, just prefix the encrypted data with the IV for use in decryption, it does not need to be secret. – zaph Mar 08 '17 at 02:12
  • The docs for the service I'm trying to use say "Decrypt the string using AES256-ECB". Are the modes interchangeable? If they `encrypt` using ECB, can I `decrypt` using CBC? – TerryMatula Mar 08 '17 at 12:33
  • You may find you cannot decrypt with OpenSSL because of your `$key`. I beleive your key should be hexadecimal. I found that values generated with Mcrypt using an invalid key cannot be decrypted with OpenSSL. But if use a valid key with Mcrypt, then OpenSSL can decrypt it. – Courtney Miles Aug 10 '17 at 05:50
  • The "duplicate" answer referred to is advice and not really an answer. This question is about MCRYPT_RIJNDAEL_128 which *can* be decrypted with openssl. – ryantxr Mar 05 '18 at 02:28

1 Answers1

0

This isn't an answer, but since I'm including a chunk of code, I'm putting it here. It's also lifted from a different site, but I closed the window while i was testing it by accident and can't give proper credit.

It also uses a different cipher method (ECB). But maybe it's a starting point for you. As you'll see, running this code will throw some errors, but in the vardump at the bottom, it does indeed return the encrypted text string.

Hope it helps you! I have to run out the door!

<?php

$key = "1234541413411111";
$data = "hello world";

$cipher = mcrypt_encrypt(
    MCRYPT_RIJNDAEL_128,
    $key,
    $data,
    MCRYPT_MODE_ECB);

$plain = openssl_decrypt(
    $cipher,
    'aes-128-ecb',
    $key,
    OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
);

//try to detect null padding
if (mb_strlen($iv, '8bit') % mb_strlen($plain, '8bit') == 0) {
    preg_match_all('#([\0]+)$#', $plain, $matches);
    if (mb_strlen($matches[1][0], '8bit') > 1) {
        $plain = rtrim($plain, "\0");
        trigger_error('Detected and stripped null padding. Please double-check results!');
    }
}

var_dump(
    $message,
    bin2hex($cipher),
    $plain,
    mb_strlen($message, '8bit'),
    mb_strlen($plain, '8bit'),
    $message === $plain
);
Lucas Krupinski
  • 682
  • 5
  • 16