C # Cifrado a PHP descifrado

Estoy tratando de cifrar algunos datos (de cookie) en C # y luego descifrarlos en PHP. He optado por utilizar el cifrado Rijndael. Casi lo tengo funcionando, ¡excepto que solo una parte del texto está descifrado! Comencé a trabajar desde este ejemplo:Descifrar la cadena cifrada de PHP en C #

Aquí está el texto (JSON) que estoy cifrando (información confidencial eliminada):

{"DisplayName":"xxx", "Username": "yyy", "EmailAddress":"zzz"}

Así que me conecto a la aplicación C # que crea / codifica la cookie a partir de Key y IV almacenados y luego redirige a la aplicación PHP que se supone descifra / lee la cookie. Cuando descifro la cookie, sale así:

{"DisplayName":"xxx","F�A ;��HP=D�������4��z����ť���k�#E���R�j�5�\�t. t�D��" 

ACTUALIZAR: He avanzado un poco más y este es ahora el resultado

string(96) "{"DisplayName":"xxx","Username":"yyy","EmailAddress"�)ق��-�J��k/VV-v� �9�B`7^" 

Como puede ver, comienza a descifrarlo, pero luego se desordena ...

Cuando descifre la cadena, saldrá correctamente (con el relleno, que tengo una función para eliminar el relleno), pero si cambio la cadena de prueba por un carácter, obtengo basura nuevamente:

B�nHL�Ek    �¿?�UΣlO����OЏ�M��NO/�f.M���Lƾ�CC�Y>F��~�qd�+

Aquí está el código c # que uso para generar la clave aleatoria y IV:

ACTUALIZAR: Solo estoy usando la llave estática / IV por ahora, aquí están:

Key: lkirwf897+22#bbtrm8814z5qq=498j5
IV: 741952hheeyy66#cs!9hjv887mxx7@8y

RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.BlockSize = 256;
symmetricKey.KeySize = 256;
symmetricKey.Padding = PaddingMode.Zeros;
symmetricKey.Mode = CipherMode.CBC;
string key = Convert.ToBase64String(symmetricKey.Key);
string IV = Convert.ToBase64String(symmetricKey.IV);

 Luego guardo la clave y el IV en una base de datos para recuperarlos más tarde para la codificación / decodificación.

Esta es la clase de encriptación completa:

public static class Encryption
    {
        public static string Encrypt(string prm_text_to_encrypt, string prm_key, string prm_iv)
        {
            var sToEncrypt = prm_text_to_encrypt;

            var rj = new RijndaelManaged()
            {
                Padding = PaddingMode.PKCS7,
                Mode = CipherMode.CBC,
                KeySize = 256,
                BlockSize = 256,
                //FeedbackSize = 256
            };

            var key = Encoding.ASCII.GetBytes(prm_key);
            var IV = Encoding.ASCII.GetBytes(prm_iv);
            //var key = Convert.FromBase64String(prm_key);
            //var IV = Convert.FromBase64String(prm_iv);

            var encryptor = rj.CreateEncryptor(key, IV);

            var msEncrypt = new MemoryStream();
            var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);

            var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt);

            csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
            csEncrypt.FlushFinalBlock();

            var encrypted = msEncrypt.ToArray();

            return (Convert.ToBase64String(encrypted));
        }

        public static string Decrypt(string prm_text_to_decrypt, string prm_key, string prm_iv)
        {

            var sEncryptedString = prm_text_to_decrypt;

            var rj = new RijndaelManaged()
            {
                Padding = PaddingMode.PKCS7,
                Mode = CipherMode.CBC,
                KeySize = 256,
                BlockSize = 256,
                //FeedbackSize = 256
            };

            var key = Encoding.ASCII.GetBytes(prm_key);
            var IV = Encoding.ASCII.GetBytes(prm_iv);
            //var key = Convert.FromBase64String(prm_key);
            //var IV = Convert.FromBase64String(prm_iv);

            var decryptor = rj.CreateDecryptor(key, IV);

            var sEncrypted = Convert.FromBase64String(sEncryptedString);

            var fromEncrypt = new byte[sEncrypted.Length];

            var msDecrypt = new MemoryStream(sEncrypted);
            var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);

            csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

            return (Encoding.ASCII.GetString(fromEncrypt));
        }

        public static void GenerateKeyIV(out string key, out string IV)
        {
            var rj = new RijndaelManaged()
            {
                Padding = PaddingMode.PKCS7,
                Mode = CipherMode.CBC,
                KeySize = 256,
                BlockSize = 256,
                //FeedbackSize = 256
            };
            rj.GenerateKey();
            rj.GenerateIV();

            key = Convert.ToBase64String(rj.Key);
            IV = Convert.ToBase64String(rj.IV);
        }
    }

Aquí está el código PHP que estoy usando para descifrar los datos:

    function decryptRJ256($key,$iv,$string_to_decrypt)
{
    $string_to_decrypt = base64_decode($string_to_decrypt);
    $rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $string_to_decrypt, MCRYPT_MODE_CBC, $iv);
    //$rtn = rtrim($rtn, "\0\4");
    $rtn = unpad($rtn);
    return($rtn);
}

function unpad($value)
{
    $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    //apply pkcs7 padding removal
    $packing = ord($value[strlen($value) - 1]);
    if($packing && $packing < $blockSize){
        for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--){
            if(ord($value{$P}) != $packing){
                $packing = 0;
            }//end if
        }//end for
    }//end if 

    return substr($value, 0, strlen($value) - $packing); 
}

$ky = 'lkirwf897+22#bbtrm8814z5qq=498j5'; // 32 * 8 = 256 bit key
$iv = '741952hheeyy66#cs!9hjv887mxx7@8y'; // 32 * 8 = 256 bit iv

$enc = $_COOKIE["MyCookie"];

$dtext = decryptRJ256($ky, $iv, $enc);
var_dump($dtext);

Estoy un poco inseguro acerca de esta parte, porque todo el código de ejemplo que he visto simplemente pasa la cadena codificada en base64 directamente al descifrador, pero en mi ejemplo, tengo que descodificarla en base64 antes de pasarla, de lo contrario, aparece el error que la clave y IV no son de la longitud correcta.

ACTUALIZAR: Estoy usando claves ASCII en el formato que necesita PHP. Si genero claves de la clase RijndaelManaged, no funcionan en el lado de PHP, pero puedo usar las claves que se sabe que funcionan en el lado de PHP y usarlas en el lado C # de RijndaelManaged.

Por favor, hágame saber si omití cualquier información pertinente. TIA!

Respuestas a la pregunta(2)

Su respuesta a la pregunta