0

I was using mcrypt_encrypt to encrypt a string and send back to a c# function to decrypt, All was working fine until php 7.2 and mcrypt_encrypt does not work anymore.

function addpadding($string, $blocksize = 32)
{
    $len = strlen($string);
    $pad = $blocksize - ($len % $blocksize);
    $string .= str_repeat(chr($pad), $pad);
    return $string;
}

function encrypt($string = "")
{
    

    $key = base64_decode("12345");
    $iv = base64_decode("xxxxx");

    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, addpadding($string), MCRYPT_MODE_CBC, $iv));
}


 $message=encrypt($message);   //WORKED FINE UNTIL PHP 7.2

C# Equivalent Code to decrypt:

private static String AES_decrypt(String Input)
    {
        RijndaelManaged aes = new RijndaelManaged();
        aes.KeySize = 256;
        aes.BlockSize = 256;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        aes.Key = Convert.FromBase64String("12345");
        aes.IV = Convert.FromBase64String("xxxxx");

        var decrypt = aes.CreateDecryptor();
        byte[] xBuff = null;
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
            {
                byte[] xXml = Convert.FromBase64String(Input);
                cs.Write(xXml, 0, xXml.Length);
            }

            xBuff = ms.ToArray();
        }

        String Output = Encoding.UTF8.GetString(xBuff);
        return Output;
    }

Now i have replaced mcrypt_encrypt with openssl_encrypt

function encrypt_openssl($msg) {

$key = base64_decode("12345");

$iv = base64_decode("xxxxx");
    $iv_size = openssl_cipher_iv_length('AES-256-CBC');
    if (!$iv) {
        $iv = openssl_random_pseudo_bytes($iv_size);
    }
    $encryptedMessage = openssl_encrypt(addpadding($msg), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encryptedMessage);

}

But it does not get decrypted on the C# code i am getting error: "Length of the data to decrypt is invalid."

Any help appreciated best case i want is not to change the C# code at all .

UPDATED WITH SOLUTION:

In the end i changed it and used :

function encrypt($msg)
{
$password = '12345';
$method = 'AES-256-CBC';
$texteACrypter = $msg;
return openssl_encrypt($texteACrypter, $method, $password);
}

And C#:

  static string DecryptStringFromBytesAes(byte[] cipherText, byte[] key, byte[] iv)
    {
        // Check arguments.
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException("key");
        if (iv == null || iv.Length <= 0)
            throw new ArgumentNullException("iv");

        // Declare the RijndaelManaged object
        // used to decrypt the data.
        RijndaelManaged aesAlg = null;

        // Declare the string used to hold
        // the decrypted text.
        string plaintext;

        // Create a RijndaelManaged object
        // with the specified key and IV.
        aesAlg = new RijndaelManaged { Mode = CipherMode.CBC, Padding = PaddingMode.None, KeySize = 256, BlockSize = 128, Key = key, IV = iv };

        // Create a decrytor to perform the stream transform.
        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
        // Create the streams used for decryption.
        using (MemoryStream msDecrypt = new MemoryStream(cipherText))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    // Read the decrypted bytes from the decrypting stream
                    // and place them in a string.
                    plaintext = srDecrypt.ReadToEnd();
                    srDecrypt.Close();
                }
            }
        }

        return plaintext;
    }

    public static string OpenSSLDecrypt(string encrypted, string passphrase)
    {
        //get the key bytes (not sure if UTF8 or ASCII should be used here doesn't matter if no extended chars in passphrase)
        var key = Encoding.UTF8.GetBytes(passphrase);

        //pad key out to 32 bytes (256bits) if its too short
        if (key.Length < 32)
        {
            var paddedkey = new byte[32];
            Buffer.BlockCopy(key, 0, paddedkey, 0, key.Length);
            key = paddedkey;
        }

        //setup an empty iv
        var iv = new byte[16];

        //get the encrypted data and decrypt
        byte[] encryptedBytes = Convert.FromBase64String(encrypted);
        return DecryptStringFromBytesAes(encryptedBytes, key, iv);
    }
confusedMind
  • 2,573
  • 7
  • 33
  • 74

0 Answers0