1

我有一个 C# 服务器发布到 php 服务器。PHP 端 JSON 字符串的开头缺少 16 个字符。现在 PHP 解密看起来像这样:

function Decrypt($data_base64)
{
    global $key;
    global $iv_size;

    $ciphertext_dec = base64_decode($data_base64);

    $iv_dec = substr($ciphertext_dec, 0, $iv_size);
    $ciphertext_dec = substr($ciphertext_dec, $iv_size);

    $plaintext_utf8_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
        $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);

    return  $plaintext_utf8_dec;
}

还有 C# 帖子:

        aesCrypt = new RijndaelManaged();
        aesCrypt.KeySize = 256;
        aesCrypt.BlockSize = 128;
        aesCrypt.Mode = CipherMode.CBC;
        aesCrypt.Padding = PaddingMode.Zeros;

        var started = new StartStopObject() { action = "online" };
        string jsonser1 = new JavaScriptSerializer().Serialize(started);
        Post(Encrypt(jsonser1));

    private string Encrypt(string plainStr)
    {
        aesCrypt.GenerateIV();
        byte[] encrypted;
        ICryptoTransform crypto = aesCrypt.CreateEncryptor(aesCrypt.Key, aesCrypt.IV);
        using (System.IO.MemoryStream msEncrypt = new System.IO.MemoryStream())
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, crypto, CryptoStreamMode.Write))
        {
            using (System.IO.StreamWriter swEncrypt = new System.IO.StreamWriter(csEncrypt))
            {
                swEncrypt.Write(plainStr);
            }
            encrypted = msEncrypt.ToArray();
        }
        return Convert.ToBase64String(encrypted);
    }

    public void Post(string data)
    {
        byte[] buffer = Encoding.UTF8.GetBytes("var1=" + data);
        HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(posturl);
        WebReq.Method = "POST";
        WebReq.ContentType = "application/x-www-form-urlencoded";
        WebReq.ContentLength = buffer.Length;
        System.IO.Stream PostData = WebReq.GetRequestStream();
        PostData.Write(buffer, 0, buffer.Length);
        PostData.Close();
    }

PHP 中的 vardump 和 echo 显示:

array(1) { ["var1"]=> string(128) "UahqVaE2nrxrTAijsZmjXL8QF9YmcRXdcRUREaFp7LKlhy6StrXqMc7TDmCF4qRT8fZZOZ5ovY/vHySzP2u73cs66i7nG1ywXrGiZOHa4E9yiOFFruQegIy/6yqiPXf9" } e","email":null,"realm":null,"script":null,"followtag":null "自动加入":null}

如您所见,JSON 字符串的开头正好缺少 16 个字符。( {"action":"online","email":null,"realm":null,"script":null,"followtag":null,"autojoin":null} )

4

1 回答 1

2

CryptoStream 不会自动将 IV 添加到密文中。PHP 方面正在切断消息的第一个块并将其用作 IV。

这是一些重现该问题的示例 PHP:

$ivSize = 32;

$key = hash('SHA256', 'hello world', true);
$iv = mcrypt_create_iv($ivSize);

$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key,
   "This is some sample text where the first block will be cut off.", MCRYPT_MODE_CBC, $iv);

$firstBlock = substr($cipher, 0, $ivSize);
$remainingCipher = substr($cipher, $ivSize);

$plain = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $remainingCipher, MCRYPT_MODE_CBC, $firstBlock);
echo $plain;

输出:

he first block will be cut off.
于 2013-07-06T02:24:33.047 回答