Vorgehensweise: Entschlüsseln von XML-Elementen mit symmetrischen Schlüsseln

Sie können die Klassen im System.Security.Cryptography.Xml-Namespace verwenden, um ein Element in einem XML-Dokument zu verschlüsseln. Die XML-Verschlüsselung ermöglicht Ihnen das Speichern oder Transportieren von vertraulichen XML-Dokumenten, ohne befürchten zu müssen, dass die Daten einfach gelesen werden können. In diesem Codebeispiel wird ein XML-Element mithilfe des AES-Algorithmus (Advanced Encryption Standard) entschlüsselt.

Informationen dazu, wie ein XML-Element mit dieser Prozedur verschlüsselt wird, finden Sie unter Gewusst wie: Verschlüsseln von XML-Elementen mit symmetrischen Schlüsseln.

Wenn Sie einen symmetrischen Algorithmus wie AES verwenden, um XML-Daten zu verschlüsseln, müssen Sie für das Verschlüsseln und Entschlüsseln der XML-Daten denselben Schlüssel verwenden. Für das Beispiel in dieser Prozedur wird angenommen, dass das verschlüsselte XML-Element mit demselben Schlüssel verschlüsselt wurde und dass sich die verschlüsselnden und die entschlüsselnden Beteiligten über den zu verwendenden Algorithmus und Schlüssel verständigt haben. In diesem Beispiel wird der AES-Schlüssel weder im verschlüsselten XML-Element gespeichert noch dort verschlüsselt.

Dieses Beispiel ist für Situationen geeignet, in denen eine einzelne Anwendung Daten auf Basis eines Sitzungsschlüssels, der sich im Arbeitsspeicher befindet, oder auf Basis eines starken kryptografischen Schlüssels verschlüsseln muss, der aus einem Kennwort abgeleitet wurde. Für Situationen, in denen zwei oder mehr Anwendungen verschlüsselte XML-Daten gemeinsam verwenden müssen, empfiehlt sich die Verwendung eines Verschlüsselungsschemas, dem ein asymmetrischer Algorithmus oder ein X.509-Zertifikat zugrunde liegt.

So entschlüsseln Sie ein XML-Element mit einem symmetrischen Schlüssel

  1. Verschlüsseln Sie ein XML-Element mit dem zuvor generierten Schlüssel. Verwenden Sie dazu die Verfahren, die unter Gewusst wie: Verschlüsseln von XML-Elementen mit symmetrischen Schlüsseln beschrieben sind.

  2. Suchen Sie das <EncryptedData>-Element (definiert im Standard für XML-Verschlüsselung) in einem XmlDocument-Objekt, das das verschlüsselte XML-Element enthält, und erstellen Sie ein neues XmlElement-Objekt, das dieses Element darstellt.

    XmlElement? encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
    
    Dim encryptedElement As XmlElement = Doc.GetElementsByTagName("EncryptedData")(0)
    
  3. Erstellen Sie ein EncryptedData-Objekt, indem Sie die unformatierten XML-Daten aus dem zuvor erstellten XmlElement-Objekt laden.

    EncryptedData edElement = new();
    edElement.LoadXml(encryptedElement);
    
    Dim edElement As New EncryptedData()
    edElement.LoadXml(encryptedElement)
    
  4. Erstellen Sie ein neues EncryptedXml-Objekt, und verwenden Sie dieses Objekt, um die XML-Daten zu entschlüsseln. Verwenden Sie dazu den Schlüssel, der für die Verschlüsselung verwendet wurde.

    EncryptedXml exml = new();
    
    // Decrypt the element using the symmetric key.
    byte[] rgbOutput = exml.DecryptData(edElement, Alg);
    
    Dim exml As New EncryptedXml()
    
    
    ' Decrypt the element using the symmetric key.
    Dim rgbOutput As Byte() = exml.DecryptData(edElement, Alg)
    
  5. Ersetzen Sie das verschlüsselte Element durch das neu entschlüsselte Nur-Text Element innerhalb des XML-Dokuments.

    exml.ReplaceData(encryptedElement, rgbOutput);
    
    exml.ReplaceData(encryptedElement, rgbOutput)
    

Beispiel

Für dieses Beispiel wird angenommen, dass eine Datei namens "test.xml" im selben Verzeichnis wie das kompilierte Programm vorhanden ist. Außerdem wird angenommen, dass "test.xml" ein "creditcard"-Element enthält. Sie können den folgenden XML-Code in eine Datei namens test.xml einfügen und mit diesem Beispiel verwenden.

<root>  
    <creditcard>  
        <number>19834209</number>  
        <expiry>02/02/2002</expiry>  
    </creditcard>  
</root>  
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);
        }
    }
}
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml

Module Program

    Sub Main(ByVal args() As String)
        Dim key As Aes = Nothing

        Try
            ' Create a new Aes key.
            key = Aes.Create()
            ' Load an XML document.
            Dim xmlDoc As New XmlDocument()
            xmlDoc.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 e As Exception
            Console.WriteLine(e.Message)
        Finally
            ' Clear the key.
            If Not (key Is Nothing) Then
                key.Clear()
            End If
        End Try

    End Sub


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementName As String, ByVal Key As SymmetricAlgorithm)
        ' Check the arguments.  
        ArgumentNullException.ThrowIfNull(Doc)
        ArgumentNullException.ThrowIfNull(ElementName)
        ArgumentNullException.ThrowIfNull(Key)

        ''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Find the specified element in the XmlDocument
        ' object and create a new XmlElemnt object.
        ''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(0)

        ' Throw an XmlException if the element was not found.
        If elementToEncrypt Is Nothing Then
            Throw New XmlException("The specified element was not found")
        End If

        ''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Create a new instance of the EncryptedXml class 
        ' and use it to encrypt the XmlElement with the 
        ' symmetric key.
        ''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim eXml As New EncryptedXml()

        Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
        ''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Construct an EncryptedData object and populate
        ' it with the desired encryption information.
        ''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim edElement As 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.
        Dim encryptionMethod As String = Nothing

        If TypeOf Key Is Aes Then
            encryptionMethod = EncryptedXml.XmlEncAES256Url
        Else
            ' Throw an exception if the transform is not in the previous categories
            Throw New CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption.")
        End If

        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)

    End Sub


    Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As SymmetricAlgorithm)
        ' Check the arguments.  
        If Doc Is Nothing Then
            Throw New ArgumentNullException("Doc")
        End If
        If Alg Is Nothing Then
            Throw New ArgumentNullException("Alg")
        End If
        ' Find the EncryptedData element in the XmlDocument.
        Dim encryptedElement As XmlElement = Doc.GetElementsByTagName("EncryptedData")(0)

        ' If the EncryptedData element was not found, throw an exception.
        If encryptedElement Is Nothing Then
            Throw New XmlException("The EncryptedData element was not found.")
        End If


        ' Create an EncryptedData object and populate it.
        Dim edElement As New EncryptedData()
        edElement.LoadXml(encryptedElement)
        ' Create a new EncryptedXml object.
        Dim exml As New EncryptedXml()


        ' Decrypt the element using the symmetric key.
        Dim rgbOutput As Byte() = exml.DecryptData(edElement, Alg)
        ' Replace the encryptedData element with the plaintext XML element.
        exml.ReplaceData(encryptedElement, rgbOutput)
    End Sub
End Module

Kompilieren des Codes

.NET-Sicherheit

Speichern Sie einen kryptografischen Schlüssel nie im Klartextformat, und übertragen Sie einen Schlüssel nie im Klartextformat zwischen Computern.

Wenn Sie einen symmetrischen kryptografischen Schlüssel nicht mehr benötigen, entfernen Sie ihn aus dem Arbeitsspeicher, indem Sie jedes Byte auf 0 (null) festlegen oder indem Sie die Clear-Methode der verwalteten Kryptografieklasse aufrufen.

Siehe auch