2008-11-06 8 views
5

Je voudrais lire/écrire des fichiers XML cryptés en utilisant LINQ to XML. Est-ce que quelqu'un sait comment utiliser les algorithmes de cryptage intégrés dans le .NET Framework pour crypter le Stream utilisé par l'objet XDocument? J'ai essayé, mais vous ne pouvez pas configurer le CryptoStream pour un accès en lecture/écriture. Il prend uniquement en charge Read ou Write, ce qui entraîne LINQ to XML à lancer une exception.Comment lire/écrire un fichier XML chiffré à l'aide de LINQ to XML?

Mise à jour: Ce serait bien de lire/écrire le document "à la volée", mais je suis seulement obligé de lire le fichier XML crypté, de le manipuler, puis de le réécrire crypté.

+0

Pouvez-vous clarifier ce que vous voulez faire? Est-il suffisant de lire le document entier en mémoire, de le manipuler, puis de le réécrire - ou devez-vous être capable de lire/écrire à la volée? – tvanfosson

Répondre

8

L'approche la plus simple est probablement XDocument.Load(), Linq around, puis XDocument.Save(). A partir d'une application de test rapide (aller simple sur les ressources non cédés):

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 

Swap votre ICryptoTransform favori dans la CryptoStream.

+0

J'ai essayé ceci avec la classe AesManaged pour faire le cryptage, et cette erreur parce qu'elle voulait avoir un accès en lecture/écriture au flux. Hmm ... Je vais essayer à nouveau. Merci. –

+0

comment stockez-vous les clés? –

+0

@Chris - cela dépend de l'application. Parfois, vous n'avez pas besoin de le stocker du tout. Peut-être acceptez-vous un mot de passe d'un utilisateur lors de l'exécution et générez la clé en utilisant [Rfc2898DeriveBytes] (http://msdn.microsoft.com/fr-fr/library/system.security.cryptography.rfc2898derivebytes.aspx). Dans les autres cas, vous stockez le mot de passe dans un emplacement de configuration sécurisé. Mon exemple est une démonstration du processus de cryptage/décryptage uniquement. Vous ne voulez pas utiliser la clé générée par Rijandael dans une application réelle car elle est générée par instanciation. –

0

[mise à jour: Kudos à Corbin Mars, qui (en même temps) a écrit le même, mais dans le code]

la plupart des flux sont d'une façon. J'imagine que vous auriez à:

  • créer une CryptoStream lecture à partir du (fichier etc)
  • lire les données (par exemple en XDocument)
  • faire votre code (lire le document, apporter des modifications, etc)
  • caisse
  • une nouvelle CryptoStream d'écriture (fichier, etc.) [en commençant par le même IV etc)
  • sauver le docuemnt au flux

Selon le flux sous-jacent (FileStream, MemoryStream, etc.), il se peut que vous deviez également le fermer/rouvrir complètement entre la lecture et l'écriture (c.-à-d. le CryptoStream se sentira probablement propriétaire du flux de base, et le).