我目前正在尝试构建加密的序列化程序类。目标是为用户设置或任何其他需要保存的类加密xml序列化类。
序列化程序的未加密版本可以正常工作,并允许用户更改和保存设置。 当所有设置都保留为默认设置时,加密版本将起作用。它可以从加密文件中序列化和反序列化。 但是,只要在运行时更改设置并重新保存,重新打开时的反序列化就会给出" XML文档中存在错误(19,12)。
消息='',十六进制值0x04,是无效字符。第19行, 第12位。 源=的System.Xml
问题似乎出现在反序列化逻辑中。 XmlSerializer需要一个类型来反序列化为...但是在读取文件时,我只有默认的"空白"类型。在我的脑海中,这似乎不应该是一个问题,因为班级的结构不会改变,只有实际的成员才会发生变化。价值......当事情没有被加密时它起作用,甚至在加密时也是如此。但是,由于某种原因,我还没有设法用加密来实现这一点。
奇怪的是,未加密的版本工作正常,但加密系统似乎也有效,除非它弄乱了某些东西......比如Byte []长度等等。
public dynamic Read()
{
dynamic data = Activator.CreateInstance(dataType.GetType()); //dataType is brought in from constructor, see below
try
{
ObjectXmlSerializer oxs = new ObjectXmlSerializer();
Byte[] fileBytes;
using (FileStream fs = new FileStream(path, FileMode.Open))
{
fileBytes = AesDecrypt(ReadToEnd(fs), key);
}
data = oxs.Deserialize<dynamic>(fileBytes,dataType);
return data;
}
catch
{
throw new System.ArgumentException("Error in deserialization");
}
}
反序列化发生在这里。为了让类型正确返回bObj的类型,我得引入一个示例objType ...但是这似乎引起了一个问题。
public T Deserialize<T>(Byte[] bObj,T objType)
{
using (MemoryStream ms = new MemoryStream(bObj))
{
return (T)new XmlSerializer(objType.GetType()).Deserialize(ms);
}
}
加载/保存现有设置的“设置”类中的功能
public static Settings LoadSettings()
{
Settings newSettings = new Settings();
EncryptedSerializer serializer = new EncryptedSerializer(path, newSettings, Settings.key);
//Serializer serializer = new Serializer(path, newSettings);
// check if settings were already loaded, if so read them.
// otherwise, if it's a new file, then write the defaults to it
if (new FileInfo(path).Length > 0)
{
newSettings = serializer.Read();
}
else
{
// save default user settings to file
serializer.Write();
}
return newSettings;
}
public static void SaveSettings(Settings settings)
{
EncryptedSerializer serializer = new EncryptedSerializer(path, settings, Settings.key);
//Serializer serializer = new Serializer(path, settings);
serializer.Write();
}
}
非常感谢帮助 编辑:aesdecrypt()代码
public static Byte[] AesDecrypt(Byte[] src,Key key)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
try
{
myRijndael.Mode = CipherMode.CBC;
myRijndael.Key = key.keyBytes;
myRijndael.IV = key.initVectorBytes;
myRijndael.Padding = key.paddingMode;
using (ICryptoTransform decryptor = myRijndael.CreateDecryptor())
using (MemoryStream msDecrypt = new MemoryStream())
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(src, 0, src.Length);
csDecrypt.FlushFinalBlock();
}
myRijndael.Clear();
return msDecrypt.ToArray();
}
}
catch
{
throw new System.ArgumentException("Error in decryption");
}
//finally
//{
// //myRijndael.Clear();
//}
}
}