加密在PHP中,解密在C#中使用AES / Rijndael算法(WP7 / Silverlight的)

问题描述:

我是用PHP编写我的Android应用程序没有太多的麻烦REST服务。 !现在,我想在Windows Phone应用程序使用它,我越来越疯狂已

I was using a REST service written in PHP in my android app without much trouble. Now I'm trying to use it in a Windows Phone app and I'm getting crazy already!

我知道什么至今:的 Silverlight将只接受在AES CBC模式和PKCS7填充。

我得到什么:填充是无效的不能删除异常时(见底部完整的代码):

What I get: "Padding is invalid and can not be removed" exception at (see full code at the bottom):

plaintext = srDecrypt.ReadToEnd();

如果我隐窝和解密在C#中,使用相同的configs,它工作正常。当我尝试从PHP加密的字符串在C#中decript时,出现上述错误

If I crypt and decrypt in C#, using the same configs, it works fine. When I try to decript in C# from a PHP crypted string, it fails with the error mentioned above.

我的PHP脚本执行以下操作:

My PHP script do the following:

function encrypt128($message) {
    $vector = "DB96A56CCA7A69FC";
    $key = "6DBC44F54CA3CFDEDDCA140CA46A99C1"; // PHP md5 function leaves it in lower case, so I just copied the key from C# debug.

    //PKCS7 Padding
    $block = mcrypt_get_block_size('rijndael_128', 'cbc');
    $pad = $block - (strlen($message) % $block);
    $message.= str_repeat(chr($pad), $pad);

    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
    mcrypt_generic_init($cipher, $key, $vector);
    $result = mcrypt_generic($cipher, $message);
    mcrypt_generic_deinit($cipher);

    return base64_encode($result);
}

和在C#中(的Silverlight / Windows Phone 7的)我用下面的解密

And in C# (Silverlight / Windows Phone 7) I use the following to decrypt:

//Where buffer is the string data I got after calling the PHP REST service.
DecryptStringFromBytes(Convert.FromBase64String(buffer), MD5Core.GetHash("7a272d3e41372c547a272d3e41372c54"), System.Text.Encoding.UTF8.GetBytes("DB96A56CCA7A69FC"));

static string DecryptStringFromBytes(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("Key");

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

    // Create an RijndaelManaged object
    // with the specified key and IV.
    using (AesManaged rijAlg = new AesManaged())
    {
        rijAlg.Key = Key;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.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();
                }
            }
        }
    }
    return plaintext;
}



最大的问题是:什么?我做错了。

The big question is: what am I doing wrong?

在此先感谢

因此,这里的答案是:

我DROP掉了MD5屁滚尿流PHP和C#,和他们现在工作正常。

I droped the MD5 crap out of PHP and C#, and they are now working properly.

万一你丢弃在这里寻找对于同样的答案,这里是一个示例代码。不要忘了让自己的密钥和IV

Just in case you dropped here looking for the same answer, here is a sample code. Don't forget to make your own key and iv (although those bellow will work, is not recommended to use!)

PHP(虽然这些波纹管会的工作,不建议使用!):

PHP:

function encrypt128($message) {
    $vector = "0000000000000000";
    $key = "00000000000000000000000000000000";

    $block = mcrypt_get_block_size('rijndael_128', 'cbc');
    $pad = $block - (strlen($message) % $block);
    $message .= str_repeat(chr($pad), $pad);

    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
    mcrypt_generic_init($cipher, $key, $vector);
    $result = mcrypt_generic($cipher, $message);
    mcrypt_generic_deinit($cipher);

    return base64_encode($result);
}



C#:

C#:

byte[] cripted = EncryptStringToBytes("Test", System.Text.Encoding.UTF8.GetBytes("00000000000000000000000000000000"), System.Text.Encoding.UTF8.GetBytes("0000000000000000"));