2009-12-15 65 views
5

Tôi đang cố gắng mã hóa/giải mã một tệp XML. Tôi tìm thấy mẫu này để mã hóa nhưng tôi không biết cách giải mã? Bất kỳ ý tưởng? Cảm ơn!Làm thế nào để mã hóa/giải mã một tệp 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"); 

Nhưng tôi không biết làm cách nào để giải mã? Bất kỳ ý tưởng? Cảm ơn!

+2

việc kiểm tra này: http://stackoverflow.com/questions/1086049/c-encrypt-an-xml-file – PRR

+0

Did bất kỳ các câu trả lời dưới đây giúp bạn? Nếu bạn có thể chấp nhận câu hỏi đó thì câu hỏi sẽ không còn là "Chưa được trả lời" nữa? –

Trả lời

8

Something như thế này:

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 = "[email protected]=ner5sW&h59_Xe9P2za-eFr2fa&[email protected]![email protected]"; 

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

Edit:

Sani Huttunen đã chỉ ra rằng việc thực hiện tĩnh của tôi ở trên có một vấn đề hiệu suất nghiêm trọng nếu bạn sẽ được mã hóa nhiều mẩu dữ liệu bằng cách sử dụng cùng một mật khẩu . Bạn có thể đọc thêm về nó ở đây: http://jmpstart.wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/

Edit: Một thực hiện không tĩnh mà là hiệu quả hơn nếu bạn cần phải thực hiện nhiều mã hóa/decryptions sử dụng cùng một mật khẩu (~ 32ms gốc ~ 1ms mới).

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 = "[email protected]=ner5sW&h59_Xe9P2za-eFr2fa&[email protected][email protected]"; 

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

Bất kỳ lợi thế/bất lợi nào của giải pháp được trồng tại nhà này qua mã hóa XML chuẩn? – dtb

+0

Một lợi thế là bạn có thể sử dụng điều này để mã hóa/giải mã bất kỳ chuỗi nào. Thành thật mà nói tôi không biết về các phương pháp được sử dụng ở trên. Ví dụ của tôi yêu cầu mật khẩu hoặc cụm mật khẩu mà tôi đã không nhìn thấy trong ví dụ trên. Ngoài ra ví dụ ở trên chỉ dường như mã hóa các phần tử XML chứ không phải toàn bộ XML (có thể chỉ là sử dụng) –

+2

Có một lỗ hổng hiệu suất trong giải pháp của bạn. Bạn có thể đọc về nó ở đây: http://jmpstart.wordpress.com/2009/09/29/proper-use-of-rfc2898derivebytes/ –

Các vấn đề liên quan