我在我的 Android 应用程序中使用了用 PHP 编写的 REST 服务,没有遇到太多麻烦。现在我尝试在 Windows Phone 应用程序中使用它,我已经快疯了!
到目前为止我所知道的:Silverlight 将仅接受 CBC 模式下的 Aes 和 PKCS7 填充。 http://msdn.microsoft.com/en-us/library/bb352553%28v=vs.95%29
我得到的结果:“填充无效且无法删除”异常(请参阅底部的完整代码):
plaintext = srDecrypt.ReadToEnd();
如果我在 C# 中使用相同的配置进行加密和解密,则效果很好。当我尝试在 C# 中从 PHP 加密字符串进行解密时,它失败并出现上述错误。
我的 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;
}
最大的问题是:我做错了什么?
提前致谢!