如何加密/解密XML文件?

我正在尝试加密/解密XML文件。 我发现这个样本用于加密但我不知道如何解密? 任何的想法? 谢谢!

// 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"); 

但我不知道如何解密呢? 有任何想法吗? 谢谢!

像这样的东西:

 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; } } 

编辑:

Sani Huttunen指出,如果您使用相同的密码加密多个数据,我上面的静态实现会出现严重的性能问题。 你可以在这里阅读更多相关信息: http : //jmpstart.wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/

编辑:如果您需要使用相同的密码(~32ms原始~1ms新)执行多个加密/解密,则非常有效的非静态实现。

 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; } } 

在MSDN上有一个完整的例子 ,虽然使用RSA而不是TripleDES。