Partager via


Comment : chiffrer des éléments XML avec les certificats X.509

Mise à jour : novembre 2007

Vous pouvez utiliser les classes dans l'espace de noms System.Security.Cryptography.Xml pour chiffrer un élément dans un document XML. Le chiffrement XML est une façon standard d'échanger ou de stocker des données XML chiffrées, sans risque que les données soient lues facilement. Pour plus d'informations sur les normes de chiffrement XML, consultez la spécification de chiffrement du World Wide Web Consortium (W3C) à l'adresse http://www.w3.org/TR/xmldsig-core/.

Vous pouvez utiliser le chiffrement XML pour remplacer tout élément ou document XML par un élément <EncryptedData> qui contient les données XML chiffrées. L'élément <EncryptedData> peut contenir des sous-éléments qui incluent des informations sur les clés et processus utilisés pendant le chiffrement. Le chiffrement XML autorise un document à contenir plusieurs éléments chiffrés et autorise un élément à être chiffré plusieurs fois. L'exemple de code dans cette procédure vous indique comment créer un élément <EncryptedData> avec plusieurs autres sous-éléments que vous pouvez utiliser ultérieurement pendant le déchiffrement.

Cet exemple chiffre un élément XML à l'aide de deux clés. Il génère un certificat de test X.509 à l'aide du Outil Certificate Creation Tool (Makecert.exe) et enregistre le certificat dans un magasin de certificats. L'exemple récupère ensuite par programme le 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 le XML chiffré dans un nouvel élément <EncryptedData>.

Pour déchiffrer l'élément XML, appelez simplement la méthode DecryptDocument qui récupère automatiquement le certificat X.509 du 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 est approprié lorsque plusieurs applications doivent partager les données chiffrées ou lorsqu'une application doit enregistrer les données chiffrées entre chacune de ses exécutions.

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

  1. Utilisez le Outil Certificate Creation Tool (Makecert.exe) pour générer un certificat de test X.509 et le placer dans le magasin d'utilisateurs local. Vous devez générer une clé d'échange et devez rendre la clé exportable. Exécutez la commande suivante :

    makecert -r -pe -n "CN=XML_ENC_TEST_CERT" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my
    
  2. Créez un objet X509Store et initialisez-le pour ouvrir le magasin utilisateurs courant.

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

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

    Dim certCollection As X509Certificate2Collection = store.Certificates
    
    X509Certificate2Collection certCollection = store.Certificates;
    
  5. Énumérez les certificats dans le magasin et recherchez le certificat avec le nom approprié. Dans cet exemple, le certificat est appelé "CN=XML_ENC_TEST_CERT".

    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
    
    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;
        }
    }
    
  6. Fermez le magasin après que le certificat a été localisé.

    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.

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

    Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
    
    
    XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
    
  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.

    Dim eXml As New EncryptedXml()
    
    ' Encrypt the element.
    Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
    
    EncryptedXml eXml = new EncryptedXml();
    
    // Encrypt the element.
    EncryptedData edElement = 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

Imports System
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 'Main


    Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
        ' Check the arguments.  
        If Doc Is Nothing Then
            Throw New ArgumentNullException("Doc")
        End If
        If ElementToEncryptName Is Nothing Then
            Throw New ArgumentNullException("ElementToEncrypt")
        End If
        If Cert Is Nothing Then
            Throw New ArgumentNullException("Cert")
        End If
        ''''''''''''''''''''''''''''''''''''''''''''''''
        ' 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
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 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");

        }

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

Cet exemple suppose qu'un fichier nommé "test.xml" existe 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 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>

Compilation du code

Sécurité

Le certificat X.509 utilisé dans cet exemple est utilisé uniquement à des fins de test. Les applications doivent utiliser un certificat X.509 généré par une autorité de confiance ou utiliser un certificat généré par Microsoft Windows Certificate Server.

Voir aussi

Tâches

Comment : déchiffrer des éléments XML avec les certificats X.509

Référence

System.Security.Cryptography.Xml

Autres ressources

Chiffrement XML et signatures numériques