加密在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"));