【发布时间】:2013-11-16 17:23:10
【问题描述】:
我在我的 android 应用程序中使用了一个用 PHP 编写的 REST 服务,没有太多麻烦。现在我尝试在 Windows Phone 应用程序中使用它,我已经快疯了!
目前我所知道的: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;
}
最大的问题是:我做错了什么?
提前致谢!
【问题讨论】:
-
如果您在每种方法中加密一个非常小的字符串,并比较输出,它们是否不同?怎么样?
-
如果我对“Test”进行编码,我会在 C# 中得到“eScuqAGH8L6cKaRG9ii+uw==”,在 PHP 中得到“0RysWwzyHHDnwcf0cIQ8xg==”。
-
我更改了 StreamWriter 构造函数以测试所有可用的编码类型(UTF8、Unicode、BigEndian),但 C# 仍然生成不同的编码字符串。
标签: c# php silverlight windows-phone-7 encryption