C# Encryption to PHP Decryption

孤人 提交于 2019-11-27 04:05:54

Since the string is partially OK, but there is gibberish at the end it would suggest a padding problem within the encryption which expects exact blocks of 256 bytes. I suggest setting the padding as PKCS7 (PaddingMode.PKCS7) instead of Zeros on the C# side which PHP will understand without issues (as it's the default mode on that parser).

Edit: Oops, I did not notice that you had the following in your PHP:

$enc = $_COOKIE["MyCookie"];

This is the caveat. PHP is likely not getting the encrypted data as-is and is running some urldecode sanitizing. You should print this variable to see that it really matches what is being sent from the C# code.

Edit2:

Convert the whitespaces to missing + characters from the cookie by adding this:

str_replace(' ', '+', $enc);

For posterity I'm placing the fully completed solution here.

C# Encryption Class

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,
        };

        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,
        };

        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,
        };
        rj.GenerateKey();
        rj.GenerateIV();

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

PHP Decryption Snippet

<?php
function decryptRJ256($key,$iv,$encrypted)
{
    //PHP strips "+" and replaces with " ", but we need "+" so add it back in...
    $encrypted = str_replace(' ', '+', $encrypted);

    //get all the bits
    $key = base64_decode($key);
    $iv = base64_decode($iv);
    $encrypted = base64_decode($encrypted);

    $rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
    $rtn = unpad($rtn);
    return($rtn);
}

//removes PKCS7 padding
function unpad($value)
{
    $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $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;
            }
        }
    }

    return substr($value, 0, strlen($value) - $packing); 
}
?>
<pre>
<?php

$enc = $_COOKIE["MyCookie"];

$ky = ""; //INSERT THE KEY GENERATED BY THE C# CLASS HERE
$iv = ""; //INSERT THE IV GENERATED BY THE C# CLASS HERE

$json_user = json_decode(decryptRJ256($ky, $iv, $enc), true);

var_dump($json_user);

?>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!