Проблема шифрования XML с помощью ключа RijndaelManaged - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь зашифровать элемент XML в документе XML.

Я наткнулся на ЭТОТ MSDN DOC , который показывает подход, как это сделать.

Если я использую код "как есть" в этом документе, он работает. Тем не менее, этот демонстрационный код не соответствует моему сценарию, где мне нужно сохранить зашифрованный файл XML, а затем в другое время загрузить его и затем расшифровать. Итак, я изменил демонстрационный код, чтобы сделать это, но теперь я получаю ошибку:

"Заполнение недействительно и не может быть удалено."

Я видел в других постах на SO, чтопользователи, получившие похожую ошибку, установили свойство Padding класса RijndaelManaged. Я попробовал это, используя все PKCS7, Zeros и None, но все равно получаю ошибку. Я должен упомянуть, что я применил одно и то же значение Padding к ключу для обоих методов шифрования и дешифрования.

Пожалуйста, кто-то может сказать мне, что я делаю неправильно или предложить альтернативный подход?

Пожалуйста, найдите ниже мой исправленный код (для консольного приложения) в надежде, что это поможет найти решение. Пожалуйста, назначьте пути к файлам для двух констант вверху.

PLAINTEXT XML FILE:

<?xml version="1.0" encoding="utf-8" ?><root><creditcard>
<number>19834209</number>
<expiry>02/02/2002</expiry></creditcard></root>

ИЗМЕНЕННЫЙ КОД:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml; 
using System.Xml;
namespace TestXMLEncryption
{
    class Program
    {
        private const string STR_EncryptedXmlFile = "Path of Encrypted.xml";
        private const string STR_PlainTextXmlFile = "Path of PlainText.xml";
        static void Main(string[] args)
        {
            PlainTextXmlToEncryptedXml();
            EncryptedXmlToPlainTextXml();
        }

        private static void EncryptedXmlToPlainTextXml()
        {
            using (var key = new RijndaelManaged())
            {
                try
                {
                    key.Padding = PaddingMode.PKCS7;
                    // Load an XML document.
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load(STR_EncryptedXmlFile);
                    Decrypt(xmlDoc, key);
                    Console.WriteLine("The element was decrypted");
                    Console.WriteLine(xmlDoc.InnerXml);
                    Console.ReadLine();
                }
                catch (Exception e)
                {
                    Console.WriteLine($"ERROR: {e.Message}");
                    Console.ReadLine();
                }
                finally
                {
                    // Clear the key.
                    if (key != null)
                    {
                        key.Clear();
                    }
                }
            }
        }

        private static void PlainTextXmlToEncryptedXml()
        {
            using (var key = new RijndaelManaged())
            {
                try
                {
                    key.Padding = PaddingMode.PKCS7;
                    // Load an XML document.
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load(STR_PlainTextXmlFile);
                    // Encrypt the "creditcard" element.
                    Encrypt(xmlDoc, "creditcard", key);
                    Console.WriteLine("The element was encrypted");
                    xmlDoc.Save(STR_EncryptedXmlFile);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    // Clear the key.
                    if (key != null)
                    {
                        key.Clear();
                    }
                }
            }
        }

        public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
        {
            // Find the EncryptedData element in the XmlDocument.
            XmlElement 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.
            EncryptedData edElement = new EncryptedData();
            edElement.LoadXml(encryptedElement);
            // Create a new EncryptedXml object.
            EncryptedXml 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);
        }

        public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
        {
            ////////////////////////////////////////////////
            // Find the specified element in the XmlDocument
            // object and create a new XmlElemnt object.
            ////////////////////////////////////////////////
            XmlElement 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");
            }
            //////////////////////////////////////////////////
                // Create a new instance of the EncryptedXml class 
                // and use it to encrypt the XmlElement with the 
                // symmetric key.
                //////////////////////////////////////////////////
                EncryptedXml eXml = new EncryptedXml();
            byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
            ////////////////////////////////////////////////
            // Construct an EncryptedData object and populate
            // it with the desired encryption information.
            ////////////////////////////////////////////////
            EncryptedData edElement = new EncryptedData();
            edElement.Type = EncryptedXml.XmlEncElementUrl;
            // Create an EncryptionMethod element so that the 
            // receiver knows which algorithm to use for decryption.
            // Determine what kind of algorithm is being used and
            // supply the appropriate URL to the EncryptionMethod element.
            string encryptionMethod = null;
            if (Key is TripleDES)
            {
                encryptionMethod = EncryptedXml.XmlEncTripleDESUrl;
            }
            else if (Key is DES)
            {
                encryptionMethod = EncryptedXml.XmlEncDESUrl;
            }
            else 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 if (Key is Aes)
            {
                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;
            ////////////////////////////////////////////////////
            // Replace the element from the original XmlDocument
            // object with the EncryptedData element.
            ////////////////////////////////////////////////////
            EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
        }
    }
}

1 Ответ

0 голосов
/ 04 октября 2019

Вы создаете новый ключ в своих подпрограммах Encrypt и Decrypt, поскольку вы создали объект RijndaelManaged и не установили (или не прочитали) свойство Key.

Пример кода не былнужно, потому что он использовал один и тот же объект для шифрования и дешифрования, поэтому он имел один и тот же случайный ключ для обеих операций.

...