Läs på engelska

Dela via


Anvisningar: Kryptera XML-element med symmetriska nycklar

Du kan använda klasserna i System.Security.Cryptography.Xml namnområdet för att kryptera ett element i ett XML-dokument. Med XML-kryptering kan du lagra eller transportera känslig XML, utan att behöva bekymra dig om att data lätt kan läsas. Den här proceduren krypterar ett XML-element med hjälp av AES-algoritmen (Advanced Encryption Standard).

Information om hur du dekrypterar ett XML-element som krypterades med den här proceduren finns i Så här dekrypterar du XML-element med symmetriska nycklar.

När du använder en symmetrisk algoritm som AES för att kryptera XML-data måste du använda samma nyckel för att kryptera och dekryptera XML-data. Exemplet i den här proceduren förutsätter att den krypterade XML-koden dekrypteras med samma nyckel och att krypterings- och dekrypteringsparterna är överens om vilken algoritm och nyckel som ska användas. Det här exemplet lagrar eller krypterar inte AES-nyckeln i den krypterade XML-koden.

Det här exemplet är lämpligt för situationer där ett enda program behöver kryptera data baserat på en sessionsnyckel som lagras i minnet, eller baserat på en kryptografiskt stark nyckel som härletts från ett lösenord. För situationer där två eller flera program behöver dela krypterade XML-data bör du överväga att använda ett krypteringsschema baserat på en asymmetrisk algoritm eller ett X.509-certifikat.

Så här krypterar du ett XML-element med en symmetrisk nyckel

  1. Generera en symmetrisk nyckel med hjälp av Aes klassen. Den här nyckeln används för att kryptera XML-elementet.

    C#
    Aes? key = null;
    
    try
    {
        // Create a new AES key.
        key = Aes.Create();
    
  2. Skapa ett XmlDocument objekt genom att läsa in en XML-fil från disken. Objektet XmlDocument innehåller XML-elementet som ska krypteras.

    C#
    // Load an XML document.
    XmlDocument xmlDoc = new()
    {
        PreserveWhitespace = true
    };
    xmlDoc.Load("test.xml");
    
  3. Leta upp det angivna elementet XmlDocument i objektet och skapa ett nytt XmlElement objekt som representerar det element som du vill kryptera. I det här exemplet krypteras elementet "creditcard" .

    C#
    XmlElement? elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
    
  4. Skapa en ny instans av EncryptedXml klassen och använd den för att kryptera XmlElement med den symmetriska nyckeln. Metoden EncryptData returnerar det krypterade elementet som en matris med krypterade byte.

    C#
    EncryptedXml eXml = new();
    
    byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
    
  5. Konstruera ett EncryptedData objekt och fyll i det med URL-identifieraren för XML-krypteringselementet. Med den här URL-identifieraren kan en dekrypteringspart veta att XML:en innehåller ett krypterat element. Du kan använda fältet XmlEncElementUrl för att ange URL-identifieraren.

    C#
    EncryptedData edElement = new()
    {
        Type = EncryptedXml.XmlEncElementUrl
    };
    
  6. Skapa ett EncryptionMethod objekt som initieras till URL-identifieraren för den kryptografiska algoritm som används för att generera nyckeln. Skicka objektet EncryptionMethod till egenskapen EncryptionMethod .

    C#
    string? encryptionMethod;
    if (Key is Aes)
    {
        encryptionMethod = EncryptedXml.XmlEncAES256Url;
    }
    else
    {
        // Throw an exception if the transform is not AES
        throw new CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.");
    }
    
    edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
    
  7. Lägg till krypterade elementdata i EncryptedData objektet.

    C#
    edElement.CipherData.CipherValue = encryptedElement;
    
  8. Ersätt elementet från det ursprungliga XmlDocument objektet med elementet EncryptedData .

    C#
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    

Exempel

XML
<root>  
    <creditcard>  
        <number>19834209</number>  
        <expiry>02/02/2002</expiry>  
    </creditcard>  
</root>  
C#
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

namespace CSCrypto
{
    class Program
    {
        static void Main(string[] args)
        {
            Aes? key = null;

            try
            {
                // Create a new AES key.
                key = Aes.Create();
                // Load an XML document.
                XmlDocument xmlDoc = new()
                {
                    PreserveWhitespace = true
                };
                xmlDoc.Load("test.xml");

                // Encrypt the "creditcard" element.
                Encrypt(xmlDoc, "creditcard", key);

                Console.WriteLine("The element was encrypted");

                Console.WriteLine(xmlDoc.InnerXml);

                Decrypt(xmlDoc, key);

                Console.WriteLine("The element was decrypted");

                Console.WriteLine(xmlDoc.InnerXml);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                key?.Clear();
            }
        }

        public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
        {
            // Check the arguments.
            ArgumentNullException.ThrowIfNull(Doc);
            ArgumentNullException.ThrowIfNull(ElementName);
            ArgumentNullException.ThrowIfNull(Key);

            ////////////////////////////////////////////////
            // Find the specified element in the XmlDocument
            // object and create a new XmlElement 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();

            byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
            ////////////////////////////////////////////////
            // Construct an EncryptedData object and populate
            // it with the desired encryption information.
            ////////////////////////////////////////////////

            EncryptedData edElement = new()
            {
                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;
            if (Key is Aes)
            {
                encryptionMethod = EncryptedXml.XmlEncAES256Url;
            }
            else
            {
                // Throw an exception if the transform is not AES
                throw new CryptographicException("The specified algorithm is not supported or not recommended 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);
        }

        public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
        {
            // Check the arguments.
            ArgumentNullException.ThrowIfNull(Doc);
            ArgumentNullException.ThrowIfNull(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();
            edElement.LoadXml(encryptedElement);

            // Create a new EncryptedXml object.
            EncryptedXml exml = new();

            // 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);
        }
    }
}

Kompilera koden

.NET Security

Lagra aldrig en kryptografisk nyckel i klartext eller överför en nyckel mellan datorer i klartext. Använd i stället en säker nyckelcontainer för att lagra kryptografiska nycklar.

När du är klar med att använda en kryptografisk nyckel rensar du den från minnet genom att ange varje byte till noll eller genom att anropa Clear metoden för den hanterade kryptografiklassen.

Se även