[英]Encrypted XML file when using IXmlSerializable (c#)
如何以加密方式编写使用 IXmlSerializable 序列化的 XML 文件?
我将我的数据(包含节点的节点结构,就像文件系统文件夹一样)(反)序列化为 xml 文件:
public class DataNodeCollection : List<DataNode>, IXmlSerializable
{
internal void Serialize()
{
string sFilename = getFilename();
using (var writer = new StreamWriter(sFilename, false, Encoding.Unicode))
{
var serializer = new XmlSerializer(this.GetType(), new XmlRootAttribute("SystemNodes"));
serializer.Serialize(writer, this);
writer.Flush();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("FileFormatVersion", CurrentFormatVersion.ToString(CultureInfo.InvariantCulture));
foreach (DataNode elem in this)
{
var innerSerializer = new XmlSerializer(typeof(DataNode), new XmlRootAttribute(elem.Name));
innerSerializer.Serialize(writer, elem);
}
}
}
public class DataNode : IXmlSerializable
{
private IDictionary<string, string> _mapAttributes = new Dictionary<string, string>();
private IList<DataNode> _subNodes = new List<DataNode>();
public string Name { get; protected set; }
public void WriteXmlXmlWriter writer)
{
foreach (string sKey in _mapAttributes.Keys)
{
writer.WriteAttributeString(sKey, _mapAttributes[sKey]);
}
foreach (DataNode node in _subNodes)
{
var innerSerializer = new XmlSerializer(typeof(DataNode), new XmlRootAttribute(node.Name));
innerSerializer.Serialize(writer, node);
}
}
}
上面的代码显示了序列化代码,省略了反序列化,因为我认为不需要它来解决问题。
那么如何在反序列化之前编写加密和解密的文件呢? 加密/解密应该发生在 memory (我不想先写一个未加密的文件然后再读回加密它)
编辑:使用“加密”我的意思是该文件不应该是人类可读或不知道如何解密它的其他程序解析(对称密钥)
这是相同的实现,但有两种方法支持 Unicode 编码并可能缓解代码分析问题。
static void SerializeToEncryptedXmlFile(object graph, string filePath)
{
using (FileStream encryptedFileStream = File.Create(filePath))
{
using (AesManaged aesManaged = CreateAesManaged())
{
using
(
CryptoStream cryptoStream = new CryptoStream
(
encryptedFileStream, CreateAesManaged().CreateEncryptor(), CryptoStreamMode.Write
)
)
{
using (StreamWriter unicodeStreamWriter = new StreamWriter(cryptoStream, Encoding.Unicode))
{
{
new XmlSerializer(typeof(CharacterData)).Serialize(unicodeStreamWriter, CharacterData.RandomInstance);
// If you dont use a using statement for the cryptoStream,
// Don't forget to call FlushFinalBlock yourself
// Or you will have padding problems.
// cryptoStream.FlushFinalBlock();
}
}
}
}
}
}
public static TResult DeserializeFromEncryptedXmlFile<TResult>(string filePath)
{
using (FileStream encryptedFileStream = File.OpenRead(filePath))
{
using (AesManaged aesManaged = CreateAesManaged())
{
using
(
CryptoStream cryptoStream = new CryptoStream
(
encryptedFileStream, aesManaged.CreateDecryptor(), CryptoStreamMode.Read
)
)
{
using (StreamReader unicodeStreamReader = new StreamReader(cryptoStream))
{
return (TResult)new XmlSerializer(typeof(CharacterData)).Deserialize(unicodeStreamReader);
}
}
}
}
}
用法如下:
SerializeToEncryptedXmlFile(CharacterData.RandomInstance, "c:\\temp\\enc.xml");
CharacterData instance = DeserializeFromEncryptedXmlFile<CharacterData>("c:\\temp\\enc.xml");
要实现完全加密,请将CryptoStream
实例传递给 XmlSerializer。
这是一个使用 AesManaged 的示例,涵盖了加密和解密。
注意:CharacterData 是一些 XML 可序列化 class ,这里不相关。
// Returns AesManaged with 256 bit key, 128 bit IV, PKCS7 padding and using CBC mode
private static AesManaged CreateAesManaged()
{
return new AesManaged()
{
Key = Encoding.ASCII.GetBytes("This is the key%This is the key%"),
IV = Encoding.ASCII.GetBytes("This is the IV%%")
};
}
static void Main(string[] args)
{
// Serialization / Encryption:
using (FileStream encryptedFileStream = File.Create("C:\\temp\\enc.xml"))
{
using
(
CryptoStream cryptoStream = new CryptoStream
(
encryptedFileStream, CreateAesManaged().CreateEncryptor(), CryptoStreamMode.Write
)
)
{
new XmlSerializer(typeof(CharacterData)).Serialize(cryptoStream, CharacterData.RandomInstance);
// If you dont use a using statement for the cryptoStream,
// Don't forget to call FlushFinalBlock yourself
// Or you will have padding problems.
// cryptoStream.FlushFinalBlock();
}
}
// De-Serialization / Decryption:
using (FileStream encryptedFileStream = File.OpenRead("C:\\temp\\enc.xml"))
{
using
(
CryptoStream cryptoStream = new CryptoStream
(
encryptedFileStream, CreateAesManaged().CreateDecryptor(), CryptoStreamMode.Read
)
)
{
CharacterData instance = (CharacterData)new XmlSerializer(typeof(CharacterData)).Deserialize(cryptoStream);
}
}
Console.ReadLine();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.