我正在通过DataContractSerializer序列化一个对象而没有任何问题。
但是,如果我现在尝试将此对象序列化为加密文件,则在反序列化时会出现异常。
这是我的代码:
public static bool SerializeDataContract<t>(Stream fileStream, t o, bool bCrypt = false)
{
DataContractSerializer serializer = new DataContractSerializer(typeof(t));
if(bCrypt)
{
TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
crypt.IV = CRYPT_INIT_VECTOR;
crypt.Key = CRYPT_KEY;
crypt.Padding = PaddingMode.Zeros;
using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateEncryptor(), CryptoStreamMode.Write))
{
serializer.WriteObject(cryptoStream, o);
cryptoStream.Close();
}
}
else
serializer.WriteObject(fileStream, o);
return true;
}
public static bool DeserializeDataContract<t>(Stream fileStream, out t o, bool bCrypt = false)
{
o = default(t);
try
{
DataContractSerializer serializer = new DataContractSerializer(typeof(t));
if(bCrypt)
{
TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
crypt.IV = CRYPT_INIT_VECTOR;
crypt.Key = CRYPT_KEY;
crypt.Padding = PaddingMode.Zeros;
using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read))
{
//TraceXML(cryptoStream);
o = (t)serializer.ReadObject(cryptoStream);
cryptoStream.Close();
}
}
else
{
o = (t)serializer.ReadObject(fileStream);
}
}
catch(Exception ex)
{
return false;
}
return true;
}
如果我用bCrypt = false调用这两个函数,一切都按预期工作。但是,如果我用bCrypt = true调用函数,则在反序列化时会出现异常。
异常(从德语翻译成英语):SerializationException:根级别的数据无效。
如果我跟踪解密后读取的数据,那么数据对我来说似乎没问题,就像它看起来就像没有加密的序列化一样。
您知道吗,我的代码中的错误在哪里?
或者是否无法对DataContractSerializer使用加密?
答案 0 :(得分:1)
问题是加密数据用零填充,因此原始数据的长度不明显。
这是删除它们的一种方法,以便反序列化工作:
using(var cryptoStream =
new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read))
{
using(var reader = new StreamReader(cryptoStream))
{
var s = reader.ReadToEnd().TrimEnd(new char[]{'\0'});
using(var stream = new MemoryStream(Encoding.ASCII.GetBytes(s)))
{
o = (t)serializer.ReadObject(stream);
}
}
}
答案 1 :(得分:0)
如果您将文件保存到文件后我认为您可以轻松了解问题所在
在加密前将其与序列化文件进行比较。
如果他们是平等的,那么在解密者完成其工作之前你就过早地对其进行反序列化。
我认为你不需要拨打cryptoStream.Close();
Call Flush()来代替
我会使用memoryStream作为缓冲区,而不是直接将CryptoStream传递给DataContractSerializer,反之亦然。