1

我想使用加密的 xml 文件作为应用程序资源,以便轻松绑定 xaml 数据。Xml 文件在不同的应用程序中被加密。我可以使用未加密的 xml 进行数据绑定。我不能对加密的 xml 使用相同的方法,因为文件在加载时是加密的。我必须先解密它才能使用它。问题是,我在哪里放解密算法?

在这里我如何创建加密文件(省略了解密和验证解密数据的代码)

            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 文件作为应用程序资源?

4

1 回答 1

1

两种选择,一种是快速的,一种是干净的……

选项 1(快速):在加载应用程序之前解密文件

如果你解密你的文件,在 app.xaml.cs 中调用 base.OnStartup(e) 之前,它应该可以工作......

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(干净):自定义 XmlDataProvider 来处理加密的 XML 文件

另一种选择是编写一个自定义 XmlDataProvider,比如EncryptedXmlDataProvider,它包含一个EncryptedSource属性和一些其他属性来指定如何解密文件。设置属性EncryptedXmlDataProvider时可以解密文件。EncryptedSource这样,数据是可混合的,并且您拥有可重用的类型。比上面提出的解决方案多一点工作但更清洁。

于 2013-04-04T12:15:59.353 回答