Freigeben über


Vorgehensweise: Verschlü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. Dieses Verfahren verschlüsselt ein XML-Element mithilfe des AES-Algorithmus (Advanced Encryption Standard).

Informationen dazu, wie ein XML-Element entschlüsselt wird, das mit dieser Vorgehensweise verschlüsselt wurde, finden Sie unter Gewusst wie: Entschlü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 Vorgehensweise wird angenommen, dass das verschlüsselte XML-Element mit demselben Schlüssel entschlüsselt wird 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 verschlüsseln Sie ein XML-Element mit einem symmetrischen Schlüssel

  1. Generieren Sie mit der Aes-Klasse einen symmetrischen Schlüssel. Dieser Schlüssel wird dazu verwendet, das XML-Element zu verschlüsseln.

    Aes? key = null;
    
    try
    {
        // Create a new AES key.
        key = Aes.Create();
    
    Dim key As Aes = Nothing
    
    Try
        ' Create a new Aes key.
        key = Aes.Create()
    
  2. Erstellen Sie ein XmlDocument-Objekt, indem Sie eine XML-Datei von einem Datenträger laden. Das XmlDocument-Objekt enthält das zu verschlüsselnde XML-Element.

    // Load an XML document.
    XmlDocument xmlDoc = new()
    {
        PreserveWhitespace = true
    };
    xmlDoc.Load("test.xml");
    
    ' Load an XML document.
    Dim xmlDoc As New XmlDocument()
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
  3. Suchen Sie das angegebene Element im XmlDocument-Objekt, und erstellen Sie ein neues XmlElement-Objekt, das dem Element entspricht, das Sie verschlüsseln möchten. In diesem Beispiel wird das "creditcard"-Element verschlüsselt.

    XmlElement? elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
    
    Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementName)(0)
    
  4. Erstellen Sie eine neue Instanz der EncryptedXml-Klasse, und verwenden Sie diese Instanz, um das XmlElement mit dem symmetrischen Schlüssel zu verschlüsseln. Die EncryptData-Methode gibt das verschlüsselte Element als Array von verschlüsselten Bytes zurück.

    EncryptedXml eXml = new();
    
    byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
    
    Dim eXml As New EncryptedXml()
    
    Dim encryptedElement As Byte() = eXml.EncryptData(elementToEncrypt, Key, False)
    
  5. Erstellen Sie ein EncryptedData-Objekt, und weisen Sie ihm den URL-Bezeichner des XML-Verschlüsselungselements zu. Dieser URL-Bezeichner teilt einem entschlüsselnden Teilnehmer mit, dass das XML-Dokument ein verschlüsseltes Element enthält. Sie können das XmlEncElementUrl-Feld verwenden, um den URL-Bezeichner anzugeben.

    EncryptedData edElement = new()
    {
        Type = EncryptedXml.XmlEncElementUrl
    };
    
    Dim edElement As New EncryptedData()
    edElement.Type = EncryptedXml.XmlEncElementUrl
    
  6. Erstellen Sie ein EncryptionMethod-Objekt, das mit dem URL-Bezeichner des kryptografischen Algorithmus initialisiert wird, mit dem der Schlüssel generiert wurde. Übergeben Sie das EncryptionMethod-Objekt an die EncryptionMethod-Eigenschaft.

    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);
    
    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)
    
  7. Fügen Sie die verschlüsselten Elementdaten dem EncryptedData-Objekt hinzu.

    edElement.CipherData.CipherValue = encryptedElement;
    
    edElement.CipherData.CipherValue = encryptedElement
    
  8. Ersetzen Sie das Element aus dem ursprünglichen XmlDocument-Objekt durch das EncryptedData-Element.

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    

Beispiel

<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. Verwenden Sie stattdessen einen sicheren Schlüsselcontainer, um kryptografische Schlüssel zu speichern.

Wenn Sie einen 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