How to encrypt/decrypt XML element inside a XML document

Sukhpinder Singh - May 12 '21 - - Dev Community

Prerequisites

Learn about different encryption techniques like symmetric or asymmetric encryption.

Symmetric v/s Asymmetric Encryption

The article demonstrates how to encrypt and decrypt XML tags inside an XML document using symmetric keys.

Consider an example of an XML doc that contains credit card information like card number, expiry date,, etc. It is recommended never to store such “ sensitive information” in plain text. Let’s learn how to “ encrypt sensitive information and decrypt when required”.

XML Doc Example



<root> <creditcard> <number>1234567890</number> <expiry>02/02/2020</expiry> </creditcard> </root>


Enter fullscreen mode Exit fullscreen mode

Encrypt an XML element

Generate a key using the AES class. The generated key will be utilized to encrypt the XML element.



Aes key = null; try {key = Aes.Create();


Enter fullscreen mode Exit fullscreen mode

Create an XmlDocument instance by loading an XML file. The XmlDocument instance includes the XML element to encrypt.



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


Enter fullscreen mode Exit fullscreen mode

Find the specified XML element in the doc instance and generate a new XmlElement object to represent the element you want to encrypt. In this example, the "creditcard" element is encrypted.



XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;


Enter fullscreen mode Exit fullscreen mode

Please create a new instance of the Encrypted Xml class and utilise it to encrypt the XmlElement with the symmetric key. The EncryptData method returns the encrypted element as an array of encrypted bytes.



EncryptedXml eXml = new EncryptedXml(); byte[] e= eXml.EncryptData(elementToEncrypt, Key, false);


Enter fullscreen mode Exit fullscreen mode

Construct an EncryptedData instance and populate it with the URL identifier of the XML Encryption element.



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


Enter fullscreen mode Exit fullscreen mode

Create an Encryption Method instance that is initialized used to generate the key. Pass the EncryptionMethod object to the EncryptionMethod property.



string encryptionMethod = null;

if (Key is Aes){ encryptionMethod = EncryptedXml.XmlEncAES256Url;}else{ throw new CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.");}

edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);


Enter fullscreen mode Exit fullscreen mode

Add the encrypted tag data to the Encrypted Data instance.



edElement.CipherData.CipherValue = e;


Enter fullscreen mode Exit fullscreen mode

Replace the tag from the original XML Document instance with the Encrypted tag element.



EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);


Enter fullscreen mode Exit fullscreen mode

Complete Code



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

    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
    if (elementToEncrypt == null)
    {
        throw new XmlException("The XML element was not found");
    }

    EncryptedXml eXml = new EncryptedXml();

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

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

    string encryptionMethod = null;

    if (Key is Aes)
    {
        encryptionMethod = EncryptedXml.XmlEncAES256Url;
    }
    else
    {
        throw new CryptographicException("The specified algorithm is not supported.");
    }

    edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
    edElement.CipherData.CipherValue = encryptedElement;
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}


Enter fullscreen mode Exit fullscreen mode

Output



Aes key = null;
key = Aes.Create();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("info.xml");
Encrypt(xmlDoc, "creditcard", key);
Console.WriteLine(xmlDoc.InnerXml);
//Output
//<root>       
//<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" //xmlns="http://www.w3.org/2001/04/xmlenc#"><EncryptionMethod //Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
//<CipherData>
//<CipherValue>5sAuDgWH+OxxxolHu1rE2TDf6+KzQGgd9gO1WmRypV/Rart93gDym//ZGMHpwZM/knOzKLysTVtq2GSQmWTGur/yUEI76dmy3XA9FfgOi8GNTr0iFQX/rWAuJ//bwdDhsCxh5O41dMfucOIKj9uGVVOeyIQiRSstXUskX/NSUVXViSHK3rfH2zqXVh7+g//74Hs8db</CipherValue></CipherData></EncryptedData>
//</root>


Enter fullscreen mode Exit fullscreen mode

Decrypt an XML element

Find the <EncryptedData> element in an XmlDocument instance that includes the encrypted XML and creates a new XmlElement object to represent that element.



XmlElement encryptedElement = Doc.GetElementsByTagName(“EncryptedData”)[0] as XmlElement;


Enter fullscreen mode Exit fullscreen mode

Create an EncryptedData object by loading the raw XML data from the previously created XmlElement object.



EncryptedData edElement = new EncryptedData();edElement.LoadXml(encryptedElement);


Enter fullscreen mode Exit fullscreen mode

Please create a new EncryptedXml object and utilise it to decrypt the XML data using the same key that was used for encryption.



EncryptedXml exml = new EncryptedXml();byte[] rgbOutput = exml.DecryptData(edElement, Alg);


Enter fullscreen mode Exit fullscreen mode

Replace the encrypted element with the recently decrypted plaintext element within the XML document.



exml.ReplaceData(encryptedElement, rgbOutput);


Enter fullscreen mode Exit fullscreen mode

Complete Code



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

    XmlElement encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;

    if (encryptedElement == null)
    {
        throw new XmlException("The XML element was not found.");
    }

    EncryptedData edElement = new EncryptedData();
    edElement.LoadXml(encryptedElement);

    EncryptedXml exml = new EncryptedXml();

    byte[] rgbOutput = exml.DecryptData(edElement, Alg);
    exml.ReplaceData(encryptedElement, rgbOutput);
}


Enter fullscreen mode Exit fullscreen mode

Output



Decrypt(xmlDoc, key);
Console.WriteLine(xmlDoc.InnerXml);
//Output
//<root>
//<creditcard>
//  <number>1234567890</number>
//  <expiry>02/02/2020</expiry>
//</creditcard>
//</root>


Enter fullscreen mode Exit fullscreen mode

Thank you for reading. I hope you like the article..!!

Orginal Medium Story Buy Me A Coffee

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .