Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用RijndaelManaged密钥加密XML时出现问题_C#_Encryption_Rijndaelmanaged_Xml Encryption - Fatal编程技术网

C# 使用RijndaelManaged密钥加密XML时出现问题

C# 使用RijndaelManaged密钥加密XML时出现问题,c#,encryption,rijndaelmanaged,xml-encryption,C#,Encryption,Rijndaelmanaged,Xml Encryption,我正在尝试加密XML文档中的XML元素 我遇到了一个展示如何做到这一点的方法 如果我在这个文档中使用“原样”代码,它就会工作。但是,这个演示代码不适合我的场景,我需要保存加密的XML文件,然后在另一个时间加载并解密它。因此,我修改了演示代码来实现这一点,但现在我得到了错误: 填充无效,无法删除 我在上的其他帖子中看到,出现类似错误的用户设置了RijndaelManaged类的Padding属性。我尝试使用所有的PKCS7、zero和None,但仍然得到了错误。我应该提到,我对加密和解密方法的密钥

我正在尝试加密XML文档中的XML元素

我遇到了一个展示如何做到这一点的方法

如果我在这个文档中使用“原样”代码,它就会工作。但是,这个演示代码不适合我的场景,我需要保存加密的XML文件,然后在另一个时间加载并解密它。因此,我修改了演示代码来实现这一点,但现在我得到了错误:

填充无效,无法删除

我在上的其他帖子中看到,出现类似错误的用户设置了
RijndaelManaged
类的
Padding
属性。我尝试使用所有的
PKCS7
zero
None
,但仍然得到了错误。我应该提到,我对加密和解密方法的密钥应用了相同的
Padding

我做错了什么,或者有其他方法吗

下面是我修改后的代码(用于控制台应用程序)。请为顶部的两个常量指定文件路径

纯文本XML文件:

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

您正在加密和解密例程中创建一个新密钥,因为您创建了RijndaelManaged对象,但没有设置(或读取)key属性


示例代码不需要这样做,因为它使用相同的对象进行加密和解密,所以这两个操作都有相同的随机密钥。

谢谢您的回复,但是我该如何更改代码呢?抱歉,我不熟悉加密API。@Cleve您需要有一个一致的密钥。一种可能的方法是提示输入密码,并使用Rfc2898DeriveBytes导出密钥。。。但这是非常开放的。再次感谢。我仍然不知道代码是什么样子的?也就是说,我应该在哪些对象上设置哪些属性,使用哪些属性?我希望用户交互是不必要的。我不想引入这样的减速。@Cleve您需要在当前设置填充的位置将
key.key
设置为加密和解密之间的相同内容。硬编码密钥不安全,随机密钥不起作用(当前行为)。开始硬编码,看到它的工作,移动到更安全的东西。嗨,我已经做了你的建议。因此,我硬编码了一个
常量字符串myKey=“qwerty”
。然后,在EncryptedXmlToPlainTextXml中,我设置了
key.key=Encoding.UTF8.GetBytes(myKey)和明文XMLTOEncryptedXML。但现在我得到了一个“指定的密钥不是此算法的有效大小”异常?
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);
        }
    }
}