Я хотел бы читать / писать зашифрованные файлы XML с помощью LINQ to XML. Кто-нибудь знает, как использовать алгоритмы шифрования, встроенные в .NET Framework, для шифрования потока, используемого объектом XDocument?
Я пробовал, но вы не можете настроить CryptoStream для чтения / записи. Он поддерживает только чтение или запись, что приводит к тому, что LINQ to XML генерирует исключение.
Обновление: было бы неплохо читать / писать документ «на лету», но мне нужно только прочитать зашифрованный XML-файл, манипулировать им, а затем снова записать его в зашифрованном виде.





Самый простой подход - это, вероятно, XDocument.Load (), Linq, затем XDocument.Save (). Из приложения для быстрого тестирования (не используйте удаленные ресурсы):
XDocument writeContacts = new XDocument(
new XElement("contacts",
new XElement("contact",
new XElement("name", "Patrick Hines"),
new XElement("phone", "206-555-0144",
new XAttribute("type", "home")),
new XElement("phone", "425-555-0145",
new XAttribute("type", "work")),
new XElement("address",
new XElement("street1", "123 Main St"),
new XElement("city", "Mercer Island"),
new XElement("state", "WA"),
new XElement("postal", "68042")
)
)
)
);
Rijndael RijndaelAlg = Rijndael.Create();
FileStream writeStream = File.Open("data.xml", FileMode.Create);
CryptoStream cStream = new CryptoStream(writeStream,
RijndaelAlg.CreateEncryptor(RijndaelAlg.Key, RijndaelAlg.IV),
CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cStream);
writeContacts.Save(writer);
writer.Flush();
writer.Close();
FileStream readStream = File.OpenRead("data.xml");
cStream = new CryptoStream(readStream,
RijndaelAlg.CreateDecryptor(RijndaelAlg.Key, RijndaelAlg.IV),
CryptoStreamMode.Read);
XmlTextReader reader = new XmlTextReader(cStream);
XDocument readContacts = XDocument.Load(reader);
//manipulate with Linq and Save() when needed
Замените ваш любимый ICryptoTransform на CryptoStream.
Я пробовал это с классом AesManaged для шифрования, и это ошибка, потому что он хотел иметь доступ для чтения / записи к потоку. Хм ... Попробую еще раз. Спасибо.
@Chris - это зависит от приложения. Иногда вообще не нужно хранить. Возможно, вы принимаете пароль от пользователя во время выполнения и генерируете ключ с помощью Rfc2898DeriveBytes. В других случаях вы храните пароль в безопасном месте конфигурации. Мой пример - это демонстрация только процесса шифрования / дешифрования. Вы не хотите использовать ключ, сгенерированный Rijandael, в реальном приложении, поскольку он создается для каждого экземпляра.
Это именно то, что я ищу, но я борюсь с одним битом. Как сохранить поток в физический файл? Я чувствую, что это должно быть легко, но я действительно борюсь с этим. Спасибо.
[обновление: слава Корбину Марчу, который (в то же время) написал то же самое, но в коде!]
Большинство потоков являются одностороннее. Я полагаю, вам придется:
CryptoStream из (файла и т. д.)XDocument)CryptoStream, записывающий в (файл и т. д.) [начиная с того же IV и т. д.)В зависимости от того, что является базовым потоком (FileStream, MemoryStream и т. д.), Вам также может потребоваться полностью закрыть / повторно открыть его между чтением и записью (т.е. CryptoStream, вероятно, будет чувствовать себя владельцем базового потока и будет .Close() его ).
Вы можете уточнить, чем хотите заниматься? Достаточно ли прочитать весь документ в памяти, обработать его, а затем снова записать - или вам нужно иметь возможность читать / писать на лету?