Partager via


Procédure : chiffrer des éléments XML avec des certificats X.509

Vous pouvez utiliser les classes de l'espace de noms System.Security.Cryptography.Xml pour chiffrer un élément d'un document XML. Le chiffrement XML est une méthode normalisée qui permet d'échanger et de stocker des données XML chiffrées sans que celles-ci ne puissent être lues facilement. Pour plus d’informations sur la norme de chiffrement XML, consultez la spécification W3C (World Wide Web Consortium) relative au chiffrement XML à l’adresse https://www.w3.org/TR/xmldsig-core/.

Vous pouvez utiliser le chiffrement XML pour remplacer n’importe quel élément XML ou document comportant un élément <EncryptedData> qui contient des données XML chiffrées. L’élément <EncryptedData> est susceptible de contenir des sous-éléments qui incluent des informations sur les clés et les processus utilisés pendant le chiffrement. Le chiffrement XML permet à un document de contenir plusieurs éléments chiffrés et permet à un élément d'être chiffré plusieurs fois. L’exemple de code de cette procédure vous montre comment créer un élément <EncryptedData> avec plusieurs sous-éléments que vous pourrez utiliser ultérieurement pendant le déchiffrement.

Cet exemple chiffre un élément XML à l'aide de deux clés. L’exemple récupère programmatiquement un certificat et l’utilise pour chiffrer un élément XML à l’aide de la méthode Encrypt. En interne, la méthode Encrypt crée une clé de session séparée et l'utilise pour chiffrer le document XML. Cette méthode chiffre la clé de session et l’enregistre avec l’élément XML chiffré dans un nouvel élément <EncryptedData>.

Pour déchiffrer l’élément XML, appelez la méthode DecryptDocument qui récupère automatiquement le certificat X.509 dans le magasin et exécute le déchiffrement nécessaire. Pour plus d’informations sur le déchiffrement d’un élément XML chiffré à l’aide de cette procédure, consultez Comment : déchiffrer des éléments XML avec les certificats X.509.

Cet exemple convient quand plusieurs applications doivent partager des données chiffrées ou quand une application doit enregistrer des données chiffrées entre chaque exécution.

Pour chiffrer un élément XML avec un certificat X.509

Pour pouvoir exécuter cet exemple, vous devez créer un certificat de test et l’enregistrer dans un magasin de certificats. Les instructions relatives à cette tâche sont fournies uniquement pour l’outil de création de certificats Windows (Makecert.exe).

  1. Utilisez Makecert.exe pour générer un certificat X.509 de test, puis placez-le dans le magasin de l’utilisateur local. Vous devez générer une clé d'échange et rendre cette clé exportable. Exécutez la commande suivante :

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2020 -e 01/01/2025 -sky exchange -ss my  
    
  2. Créez un objet X509Store et initialisez-le pour ouvrir le magasin de l'utilisateur actuel.

    X509Store store = new X509Store(StoreLocation.CurrentUser);
    
    Dim store As New X509Store(StoreLocation.CurrentUser)
    
  3. Ouvrez le magasin en lecture seule.

    store.Open(OpenFlags.ReadOnly);
    
    store.Open(OpenFlags.ReadOnly)
    
  4. Initialisez un X509Certificate2Collection avec tous les certificats du magasin.

    X509Certificate2Collection certCollection = store.Certificates;
    
    Dim certCollection As X509Certificate2Collection = store.Certificates
    
  5. Énumérez les certificats du magasin et recherchez le certificat portant le nom approprié. Dans cet exemple, le certificat se nomme "CN=XML_ENC_TEST_CERT".

    X509Certificate2 cert = null;
    
    // Loop through each certificate and find the certificate
    // with the appropriate name.
    foreach (X509Certificate2 c in certCollection)
    {
        if (c.Subject == "CN=XML_ENC_TEST_CERT")
        {
            cert = c;
    
            break;
        }
    }
    
    Dim cert As X509Certificate2 = Nothing
    
    ' Loop through each certificate and find the certificate 
    ' with the appropriate name.
    Dim c As X509Certificate2
    For Each c In certCollection
        If c.Subject = "CN=XML_ENC_TEST_CERT" Then
            cert = c
    
            Exit For
        End If
    Next c
    
  6. Quand vous avez trouvé le certificat, fermez le magasin.

    store.Close();
    
    store.Close()
    
  7. Créez un objet XmlDocument en chargeant un fichier XML à partir du disque. L'objet XmlDocument contient l'élément XML à chiffrer.

    XmlDocument xmlDoc = new XmlDocument();
    
    Dim xmlDoc As New XmlDocument()
    
  8. Recherchez l'élément spécifié dans l'objet XmlDocument, puis créez un objet XmlElement pour représenter l'élément que vous voulez chiffrer. Dans cet exemple, l'élément "creditcard" est chiffré.

    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
    Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
  9. Créez une instance de la classe EncryptedXml et utilisez-la pour chiffrer l'élément spécifié à l'aide du certificat X.509. La méthode Encrypt retourne l'élément chiffré en tant qu'objet EncryptedData.

    EncryptedXml eXml = new EncryptedXml();
    
    // Encrypt the element.
    EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
    
    Dim eXml As New EncryptedXml()
    
    ' Encrypt the element.
    Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
    
  10. Remplacez l'élément de l'objet XmlDocument d'origine par l'élément EncryptedData.

    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
    EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    
  11. Enregistrez l'objet XmlDocument.

    xmlDoc.Save("test.xml");
    
    xmlDoc.Save("test.xml")
    

Exemple

Cet exemple suppose qu'un fichier nommé "test.xml" se trouve dans le même répertoire que le programme compilé. Il suppose également que "test.xml" contient un élément "creditcard". Vous pouvez placer le code XML suivant dans un fichier appelé test.xml et l'utiliser avec cet exemple.

<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;
using System.Security.Cryptography.X509Certificates;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            // Create an XmlDocument object.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");

            // Open the X.509 "Current User" store in read only mode.
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);

            // Place all certificates in an X509Certificate2Collection object.
            X509Certificate2Collection certCollection = store.Certificates;

            X509Certificate2 cert = null;

            // Loop through each certificate and find the certificate
            // with the appropriate name.
            foreach (X509Certificate2 c in certCollection)
            {
                if (c.Subject == "CN=XML_ENC_TEST_CERT")
                {
                    cert = c;

                    break;
                }
            }

            if (cert == null)
            {
                throw new CryptographicException("The X.509 certificate could not be found.");
            }

            // Close the store.
            store.Close();

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

            // Save the XML document.
            xmlDoc.Save("test.xml");

            // Display the encrypted XML to the console.
            Console.WriteLine("Encrypted XML:");
            Console.WriteLine();
            Console.WriteLine(xmlDoc.OuterXml);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, X509Certificate2 Cert)
    {
        // Check the arguments.
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (ElementToEncrypt == null)
            throw new ArgumentNullException("ElementToEncrypt");
        if (Cert == null)
            throw new ArgumentNullException("Cert");

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

        //////////////////////////////////////////////////
        // Create a new instance of the EncryptedXml class
        // and use it to encrypt the XmlElement with the
        // X.509 Certificate.
        //////////////////////////////////////////////////

        EncryptedXml eXml = new EncryptedXml();

        // Encrypt the element.
        EncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);

        ////////////////////////////////////////////////////
        // Replace the element from the original XmlDocument
        // object with the EncryptedData element.
        ////////////////////////////////////////////////////
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    }
}
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates

Module Program

    Sub Main(ByVal args() As String)
        Try
            ' Create an XmlDocument object.
            Dim xmlDoc As New XmlDocument()
            ' Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")

            ' Open the X.509 "Current User" store in read only mode.
            Dim store As New X509Store(StoreLocation.CurrentUser)
            store.Open(OpenFlags.ReadOnly)
            ' Place all certificates in an X509Certificate2Collection object.
            Dim certCollection As X509Certificate2Collection = store.Certificates
            Dim cert As X509Certificate2 = Nothing

            ' Loop through each certificate and find the certificate 
            ' with the appropriate name.
            Dim c As X509Certificate2
            For Each c In certCollection
                If c.Subject = "CN=XML_ENC_TEST_CERT" Then
                    cert = c

                    Exit For
                End If
            Next c
            If cert Is Nothing Then
                Throw New CryptographicException("The X.509 certificate could not be found.")
            End If

            ' Close the store.
            store.Close()
            ' Encrypt the "creditcard" element.
            Encrypt(xmlDoc, "creditcard", cert)

            ' Save the XML document.
            xmlDoc.Save("test.xml")
            ' Display the encrypted XML to the console.
            Console.WriteLine("Encrypted XML:")
            Console.WriteLine()
            Console.WriteLine(xmlDoc.OuterXml)

        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

    End Sub


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
        ' Check the arguments.  
        ArgumentNullException.ThrowIfNull(Doc)
        ArgumentNullException.ThrowIfNull(ElementToEncryptName)
        ArgumentNullException.ThrowIfNull(Cert)
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Find the specified element in the XmlDocument
        ' object and create a new XmlElemnt object.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(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 
        ' X.509 Certificate.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        Dim eXml As New EncryptedXml()

        ' Encrypt the element.
        Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' Replace the element from the original XmlDocument
        ' object with the EncryptedData element.
        ''''''''''''''''''''''''''''''''''''''''''''''''
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
    End Sub
End Module

Compilation du code

Sécurité .NET

Le certificat X.509 utilisé dans cet exemple sert à des fins de test uniquement. Il est recommandé d’utiliser un certificat X.509 généré par une autorité de certification approuvée pour les applications.

Voir aussi