2013-04-04 45 views
1

我想使用加密的xml文件作爲應用程序資源,以實現簡單的xaml數據綁定。 Xml文件在不同的應用程序中被加密。我可以使用未加密的xml進行數據綁定。我不能使用相同的方法加密XML,因爲該文件加載時加密。我必須先解密才能使用它。問題是,我在哪裏放置解密算法?如何將加密的xml文件用作xaml數據綁定的應用程序資源?

在這裏,我如何創建加密文件(將省略對解密代碼和驗證解密後的數據)

  RijndaelManaged algorithm = null; 

      algorithm = new RijndaelManaged(); 
      string passwordBytes = "password"; //password here 
      byte[] saltBytes = Encoding.UTF8.GetBytes("salt"); // salt here (another string) 
      var p = new Rfc2898DeriveBytes(passwordBytes, saltBytes); 
      algorithm.IV = p.GetBytes(algorithm.BlockSize/8); 
      algorithm.Key = p.GetBytes(algorithm.KeySize/8); 

      var xmlDoc = new XmlDocument(); 
      xmlDoc.PreserveWhitespace = true; 
      xmlDoc.Load("Bands.xml"); 

      // Encrypt the "Bands" element. 
      Encrypt(xmlDoc, "Bands", algorithm); 
      xmlDoc.Save("encryptedBands.xml"); 

要解密,只需要調用這些(假設xmlDoc中和算法是與上述相同。

Decrypt(xmlDoc, algorithm); 

下面是加密和解密根據MSDN沒什麼特別的算法。

 public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key) 
    { 
     // Check the arguments. 
     if (Doc == null) 
      throw new ArgumentNullException("Doc"); 
     if (ElementName == null) 
      throw new ArgumentNullException("ElementToEncrypt"); 
     if (Key == null) 
      throw new ArgumentNullException("Alg"); 

     var elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement; 
     // Throw an XmlException if the element was not found. 
     if (elementToEncrypt == null) 
     { 
      throw new XmlException("The specified element was not found"); 

     } 

     var eXml = new EncryptedXml(); 

     byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false); 

     var edElement = new EncryptedData(); 
     edElement.Type = EncryptedXml.XmlEncElementUrl; 

     string encryptionMethod = null; 

     if (Key is TripleDES) 
     { 
      encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; 
     } 
     else if (Key is DES) 
     { 
      encryptionMethod = EncryptedXml.XmlEncDESUrl; 
     } 
     if (Key is Rijndael) 
     { 
      switch (Key.KeySize) 
      { 
       case 128: 
        encryptionMethod = EncryptedXml.XmlEncAES128Url; 
        break; 
       case 192: 
        encryptionMethod = EncryptedXml.XmlEncAES192Url; 
        break; 
       case 256: 
        encryptionMethod = EncryptedXml.XmlEncAES256Url; 
        break; 
      } 
     } 
     else 
     { 
      // Throw an exception if the transform is not in the previous categories 
      throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); 
     } 

     edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); 

     // Add the encrypted element data to the 
     // EncryptedData object. 
     edElement.CipherData.CipherValue = encryptedElement; 
     EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); 
    } 

    public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg) 
    { 
     // Check the arguments. 
     if (Doc == null) 
      throw new ArgumentNullException("Doc"); 
     if (Alg == null) 
      throw new ArgumentNullException("Alg"); 

     // Find the EncryptedData element in the XmlDocument. 
     var encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement; 

     // If the EncryptedData element was not found, throw an exception. 
     if (encryptedElement == null) 
     { 
      throw new XmlException("The EncryptedData element was not found."); 
     } 


     // Create an EncryptedData object and populate it. 
     var edElement = new EncryptedData(); 
     edElement.LoadXml(encryptedElement); 

     // Create a new EncryptedXml object. 
     var exml = new EncryptedXml(); 


     // Decrypt the element using the symmetric key. 
     byte[] rgbOutput = exml.DecryptData(edElement, Alg); 

     // Replace the encryptedData element with the plaintext XML element. 
     exml.ReplaceData(encryptedElement, rgbOutput); 

    } 

我想使用加密的xml數據作爲數據源,以便在xaml中進行簡單的數據綁定。我在應用程序級聲明xml數據以用於應用程序範圍的訪問。以下是我在App.xaml中聲明的方法。

<Application.Resources> 
    <ResourceDictionary> 
     <XmlDataProvider x:Key="encryptedBandsDataSource" Source="/RemoteConfigurator;component/encryptedBands.xml" d:IsDataSource="True"/> 
    </ResourceDictionary> 
</Application.Resources> 

問題是,我需要在App.xaml加載前解密xml文件。有沒有可能做到這一點。我怎麼做。我在哪裏解密XML文件?

總之,我該如何使用加密的xml文件作爲應用程序資源?

回答

1

兩個選項,一個快速和乾淨的...

選項1(快速):加載應用程序

之前解密文件如果您解密文件,base.OnStartup之前( E)被稱爲app.xaml.cs,它應該工作...

using System.Windows; 

namespace MainApplication 
{ 
    /// <summary> 
    /// Interaction logic for App.xaml 
    /// </summary> 
    public partial class App 
    { 
     protected override void OnStartup(StartupEventArgs e) 
     { 
      DecryptXml(); 
      base.OnStartup(e); 

      MainBootstrapper bootstrapper = new MainBootstrapper(); 
      bootstrapper.Run(); 
     } 
    } 

}

選項2(CLE一):自定義XmlDataProvider處理加密的XML文件

另一種方法是編寫自定義XmlDataProvider,說EncryptedXmlDataProvider,其持有EncryptedSource財產和其他一些屬性來指定如何解密文件。 EncryptedXmlDataProvider可以解密文件,當設置EncryptedSource屬性。這樣,數據是可混合的,並且您有一個可重用的類型。多一點工作,但比上面提出的解決方案要乾淨得多。

+0

所以這是調用app.xaml之前加載方法的地方。謝謝你,先生。無論如何,任何混合能夠讀取和消化文件的機會? – 2013-04-04 12:27:50

+1

我已經更新了我的答案,希望它有幫助! – Marc 2013-04-04 13:03:23

+0

哇。我從來沒有想過這是可能的。謝謝你,先生。 – 2013-04-04 13:44:59

相關問題