How can I write a XML-File to which I serialize using IXmlSerializable in an encrypted way?
I (de-)serialize my data (a structure of nodes containig nodes, just like filesystemfolders) into a xml-File:
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);
}
}
}
The code above shows the serialilzation-code, deserialisation is omitted because I don't think its needed to get the problem.
So how can I write the file encrypted and decrypt it before deserialising? The encryption/decryption should happen in memory (I don't want to write an unencrypted file first and read it back to encrypt it)
edit: With "encryption" I mean the file should not be human readable or parseable by other programs without knowing how to decrypt it (symmetric key)
UPDATE 1:
Here is the same implementation but as two methods supporting Unicode encoding and probably mitigating the code analysis issues.
And the usage is as follows:
ORIGINAL ANSWER:
To achieve complete encryption, pass a
CryptoStream
instance to the XmlSerializer.Here is a sample using AesManaged covering both encryption and decryption.
Note: CharacterData is some XML serializable class which is not relevant here.