locked
Encrypt xml elements before save RRS feed

  • Question

  • User-317791795 posted

    Hi,

    I am trying to encrypt XML elements before saving.

    Below is the code to get values and save.

         XmlDocument xmlDoc = new XmlDocument();
         xmlDoc.Load("../../Info.xml");
         XmlElement ParentElement = xmlDoc.CreateElement("Details");
         XmlElement userID = xmlDoc.CreateElement("ID");
         userID.InnerText = strName;
         XmlElement userPwd = xmlDoc.CreateElement("Pwd");
         userPwd.InnerText = strPwd;
         XmlElement startDate = xmlDoc.CreateElement("Start");
         startDate.InnerText = dtStart.ToString();
         XmlElement expiryDate = xmlDoc.CreateElement("Expiry");
         expiryDate.InnerText = dtExpiry.ToString();
         ParentElement.AppendChild(userID);
         ParentElement.AppendChild(userPwd);
         ParentElement.AppendChild(startDate);
         ParentElement.AppendChild(expiryDate);
         xmlDoc.DocumentElement.AppendChild(ParentElement);
         xmlDoc.Save("../../Info.xml");

    Now I have a private string (code shown below) which can encrypt the inner xml contents before save

         private string Encrypt(string clearText)
            {
                string EncryptionKey = "MAKV2SPBNI99212";
                byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
                using (Aes encryptor = Aes.Create())
                {
                    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                    encryptor.Key = pdb.GetBytes(32);
                    encryptor.IV = pdb.GetBytes(16);
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(clearBytes, 0, clearBytes.Length);
                            cs.Close();
                        }
                        clearText = Convert.ToBase64String(ms.ToArray());
                    }
                }
                return clearText;
            }

    I am passing the innerxml contents(shown below) and `clearText` string encrypts the contents.

        Encrypt(xmlUserDoc.InnerXml);

    Now how can I save those encrypted contents to the xml file?

    Tuesday, October 25, 2016 7:16 AM

All replies

  • User-1838255255 posted

    Hi vickyt5,

    According to your description , I make a sample for your reference , This sample Encrypt one xml document , then save it , you can check it in test1 . Here is the sample code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Security.Cryptography.Xml;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml;
    
    namespace XML
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Create an XmlDocument object.
                XmlDocument xmlDoc = new XmlDocument();
    
                // Load an XML file into the XmlDocument object.
                try
                {
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load("test.xml");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
    
                // Create a new CspParameters object to specify
                // a key container.
                CspParameters cspParams = new CspParameters();
                cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
                // Create a new RSA key and save it in the container.  This key will encrypt
                // a symmetric key, which will then be encryped in the XML document.
                RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
                try
                {
                    // Encrypt the "creditcard" element.
                    Encrypt(xmlDoc, "creditcard", "EncryptedElement1", rsaKey, "rsaKey");
    
    
                    // Save the XML document.
                    xmlDoc.Save("test1.xml");
    
                    // Display the encrypted XML to the console.
                    Console.WriteLine("Encrypted XML:");
                    Console.WriteLine();
                    Console.WriteLine(xmlDoc.OuterXml);
                    Decrypt(xmlDoc, rsaKey, "rsaKey");
                    xmlDoc.Save("test.xml");
                    // Display the encrypted XML to the console.
                    Console.WriteLine();
                    Console.WriteLine("Decrypted XML:");
                    Console.WriteLine();
                    Console.WriteLine(xmlDoc.OuterXml);
    
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    // Clear the RSA key.
                    rsaKey.Clear();
                }
    
    
                Console.ReadLine();
            }
    
            public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName)
            {
                // Check the arguments.
                if (Doc == null)
                    throw new ArgumentNullException("Doc");
                if (ElementToEncrypt == null)
                    throw new ArgumentNullException("ElementToEncrypt");
                if (EncryptionElementID == null)
                    throw new ArgumentNullException("EncryptionElementID");
                if (Alg == null)
                    throw new ArgumentNullException("Alg");
                if (KeyName == null)
                    throw new ArgumentNullException("KeyName");
    
                ////////////////////////////////////////////////
                // Find the specified element in the XmlDocument
                // object and create a new XmlElemnt object.
                ////////////////////////////////////////////////
                XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
                // Throw an XmlException if the element was not found.
                if (elementToEncrypt == null)
                {
                    throw new XmlException("The specified element was not found");
    
                }
                RijndaelManaged sessionKey = null;
    
                try
                {
                    //////////////////////////////////////////////////
                    // Create a new instance of the EncryptedXml class
                    // and use it to encrypt the XmlElement with the
                    // a new random symmetric key.
                    //////////////////////////////////////////////////
    
                    // Create a 256 bit Rijndael key.
                    sessionKey = new RijndaelManaged();
                    sessionKey.KeySize = 256;
    
                    EncryptedXml eXml = new EncryptedXml();
    
                    byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
                    ////////////////////////////////////////////////
                    // Construct an EncryptedData object and populate
                    // it with the desired encryption information.
                    ////////////////////////////////////////////////
    
                    EncryptedData edElement = new EncryptedData();
                    edElement.Type = EncryptedXml.XmlEncElementUrl;
                    edElement.Id = EncryptionElementID;
                    // Create an EncryptionMethod element so that the
                    // receiver knows which algorithm to use for decryption.
    
                    edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
                    // Encrypt the session key and add it to an EncryptedKey element.
                    EncryptedKey ek = new EncryptedKey();
    
                    byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
    
                    ek.CipherData = new CipherData(encryptedKey);
    
                    ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
    
                    // Create a new DataReference element
                    // for the KeyInfo element.  This optional
                    // element specifies which EncryptedData
                    // uses this key.  An XML document can have
                    // multiple EncryptedData elements that use
                    // different keys.
                    DataReference dRef = new DataReference();
    
                    // Specify the EncryptedData URI.
                    dRef.Uri = "#" + EncryptionElementID;
    
                    // Add the DataReference to the EncryptedKey.
                    ek.AddReference(dRef);
                    // Add the encrypted key to the
                    // EncryptedData object.
    
                    edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
                    // Set the KeyInfo element to specify the
                    // name of the RSA key.
    
    
                    // Create a new KeyInfoName element.
                    KeyInfoName kin = new KeyInfoName();
    
                    // Specify a name for the key.
                    kin.Value = KeyName;
    
                    // Add the KeyInfoName element to the
                    // EncryptedKey object.
                    ek.KeyInfo.AddClause(kin);
                    // 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);
                }
                catch (Exception e)
                {
                    // re-throw the exception.
                    throw e;
                }
                finally
                {
                    if (sessionKey != null)
                    {
                        sessionKey.Clear();
                    }
    
                }
    
            }
    
            public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
            {
                // Check the arguments.  
                if (Doc == null)
                    throw new ArgumentNullException("Doc");
                if (Alg == null)
                    throw new ArgumentNullException("Alg");
                if (KeyName == null)
                    throw new ArgumentNullException("KeyName");
    
                // Create a new EncryptedXml object.
                EncryptedXml exml = new EncryptedXml(Doc);
    
                // Add a key-name mapping.
                // This method can only decrypt documents
                // that present the specified key name.
                exml.AddKeyNameMapping(KeyName, Alg);
    
                // Decrypt the element.
                exml.DecryptDocument();
                
            }
    
    
        }
    }
    

    Before Xml:

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

    After Encrypt:

    <?xml version="1.0" encoding="utf-8"?> 
    <root>
        <EncryptedData Id="EncryptedElement1" 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" /><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"><EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><KeyName>rsaKey</KeyName></KeyInfo><CipherData><CipherValue>dWg91MWdqHtUydZEg+OLt1HD2rH8pFtT4LykOIwIAmcJhG1o0DFf+kAc2RWbQeQdp/vfmcMVhQzjZJMDSoJe1tdf70yQXMedH9sHMy2whxDTDmQulYlcj4i54WkZPvM5DEmV37Y3ZR6jcBX5lIznRyUkNRW5Wfm5KknD50Qz2J8=</CipherValue></CipherData><ReferenceList><DataReference URI="#EncryptedElement1" /></ReferenceList></EncryptedKey></KeyInfo><CipherData><CipherValue>uh3G4wox/gI1MDkR1vJKOF6/4lZngLNgZwFEbPHMlYsuUjiP5uD/xh9s72iHGsWH4OfmPBtrfDnutHM6ugBaT2y53mEKgLLvJ/tMQPGVEMUssFzpBc8Axesk9VbNiOLCUAKpqWG7yfAq2z2/GXpKWd9T3sPmZxxSU6RCvPFcVqQ=</CipherValue></CipherData></EncryptedData>
    </root>
    

    Best Regards,

    Eric Du

    Wednesday, October 26, 2016 7:04 AM