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