我在我的Android應用程序中使用了用PHP編寫的REST服務,沒有太大麻煩。現在我試圖在Windows Phone應用程序中使用它,我已經瘋了!在PHP中加密,使用AES/Rijndael在C#(WP7/Silverlight)中解密
我所知道的,到目前爲止:Silverlight will accept only Aes in CBC mode and PKCS7 padding.
我得到什麼:「填充是無效的不能刪除」的例外(見完整的代碼在底部):
plaintext = srDecrypt.ReadToEnd();
如果我隱窩並在C#中解密,使用相同的配置,它工作正常。當我嘗試使用PHP加密字符串在C#中進行標識時,它會因上面提到的錯誤而失敗。
我的PHP腳本執行以下操作:
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的)我用下面的解密:
//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;
}
最大的問題是:我是什麼做錯了?
在此先感謝!
如果你加密每個方法中的一個非常小的字符串,並比較輸出,他們有區別嗎?怎麼樣? – Jonathan 2012-07-24 23:58:41
如果我編碼「Test」,我會在C#中獲得「eScuqAGH8L6cKaRG9ii + uw ==」,在PHP中獲得「0RysWwzyHHDnwcf0cIQ8xg ==」。 – 2012-07-25 12:27:56
我更改了StreamWriter構造函數以測試所有可用的編碼類型(UTF8,Unicode,BigEndian),但C#仍然生成不同的編碼字符串。 – 2012-07-25 14:11:36