Come crittografare / decrittografare un file XML?

Sto cercando di crittografare / decodificare un file XML. Ho trovato questo esempio per la crittografia ma non so come decifrare? Qualche idea? Grazie!

// Load this XML file System.Xml.XmlDocument myDoc = new System.Xml.XmlDocument(); myDoc.Load(@"c:\persons.xml"); // Get a specified element to be encrypted System.Xml.XmlElement element = myDoc.GetElementsByTagName("Persons")[0] as System.Xml.XmlElement; // Create a new TripleDES key. System.Security.Cryptography.TripleDESCryptoServiceProvider tDESkey = new System.Security.Cryptography.TripleDESCryptoServiceProvider(); // Form a Encrypted XML with the Key System.Security.Cryptography.Xml.EncryptedXml encr = new System.Security.Cryptography.Xml.EncryptedXml(); encr.AddKeyNameMapping("Deskey", tDESkey); // Encrypt the element data System.Security.Cryptography.Xml.EncryptedData ed = encr.Encrypt(element, "Deskey"); // Replace the existing data with the encrypted data System.Security.Cryptography.Xml.EncryptedXml.ReplaceElement(element, ed, false); // saves the xml file with encrypted data myDoc.Save(@"c:\encryptedpersons.xml"); 

Ma non so come lo decifrerei? Qualche idea? Grazie!

Qualcosa come questo:

 public static class Encryption { private const string InitVector = "T=A4rAzu94ez-dra"; private const int KeySize = 256; private const int PasswordIterations = 1000; //2; private const string SaltValue = "d=?ustAF=UstenAr3B@pRu8=ner5sW&h59_Xe9P2za-eFr2fa&ePHE@ras!a+uc@"; public static string Decrypt(string encryptedText, string passPhrase) { byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText); byte[] initVectorBytes = Encoding.UTF8.GetBytes(InitVector); byte[] passwordBytes = Encoding.UTF8.GetBytes(passPhrase); string plainText; byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue); Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations); byte[] keyBytes = password.GetBytes(KeySize / 8); RijndaelManaged rijndaelManaged = new RijndaelManaged { Mode = CipherMode.CBC }; try { using (ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(keyBytes, initVectorBytes)) { using (MemoryStream memoryStream = new MemoryStream(encryptedTextBytes)) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) { //TODO: Need to look into this more. Assuming encrypted text is longer than plain but there is probably a better way byte[] plainTextBytes = new byte[encryptedTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); } } } } catch (CryptographicException) { plainText = string.Empty; // Assume the error is caused by an invalid password } return plainText; } public static string Encrypt(string plainText, string passPhrase) { string encryptedText; byte[] initVectorBytes = Encoding.UTF8.GetBytes(InitVector); byte[] passwordBytes = Encoding.UTF8.GetBytes(passPhrase); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue); Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations); byte[] keyBytes = password.GetBytes(KeySize / 8); RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC}; using (ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(keyBytes, initVectorBytes)) { using (MemoryStream memoryStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); encryptedText = Convert.ToBase64String(cipherTextBytes); } } } return encryptedText; } } 

Modificare:

Sani Huttunen ha sottolineato che la mia implementazione statica di cui sopra ha un grave problema di prestazioni se si crittografa più pezzi di dati utilizzando la stessa password. Puoi leggere maggiori informazioni qui: http://jmpstart.wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/

Modifica: un’implementazione non statica che è molto più efficiente se è necessario eseguire più crittografie / decrittazioni utilizzando la stessa password (~ 32 ms originale ~ 1 ms nuovo).

 public class SimpleEncryption { #region Constructor public SimpleEncryption(string password) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] saltValueBytes = Encoding.UTF8.GetBytes(SaltValue); _DeriveBytes = new Rfc2898DeriveBytes(passwordBytes, saltValueBytes, PasswordIterations); _InitVectorBytes = Encoding.UTF8.GetBytes(InitVector); _KeyBytes = _DeriveBytes.GetBytes(32); } #endregion #region Private Fields private readonly Rfc2898DeriveBytes _DeriveBytes; private readonly byte[] _InitVectorBytes; private readonly byte[] _KeyBytes; #endregion private const string InitVector = "T=A4rAzu94ez-dra"; private const int PasswordIterations = 1000; //2; private const string SaltValue = "d=?ustAF=UstenAr3B@pRu8=ner5sW&h59_Xe9P2za-eFr2fa&ePHE@ras!a+uc@"; public string Decrypt(string encryptedText) { byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText); string plainText; RijndaelManaged rijndaelManaged = new RijndaelManaged { Mode = CipherMode.CBC }; try { using (ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(_KeyBytes, _InitVectorBytes)) { using (MemoryStream memoryStream = new MemoryStream(encryptedTextBytes)) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) { //TODO: Need to look into this more. Assuming encrypted text is longer than plain but there is probably a better way byte[] plainTextBytes = new byte[encryptedTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); } } } } catch (CryptographicException exception) { plainText = string.Empty; // Assume the error is caused by an invalid password } return plainText; } public string Encrypt(string plainText) { string encryptedText; byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); RijndaelManaged rijndaelManaged = new RijndaelManaged {Mode = CipherMode.CBC}; using (ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(_KeyBytes, _InitVectorBytes)) { using (MemoryStream memoryStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); encryptedText = Convert.ToBase64String(cipherTextBytes); } } } return encryptedText; } } 

Esiste un esempio completo su MSDN , sebbene utilizzi RSA e non TripleDES.