Comment : déchiffrer des éléments XML avec des clés asymétriques

Vous pouvez utiliser les classes dans l'espace de noms System.Security.Cryptography.Xml pour chiffrer et dé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 la norme de chiffrement XML, consultez la spécification World Wide Web Consortium (W3C) XML Signature Syntax and Processing.

L'exemple de cette procédure déchiffre un élément XML qui a été chiffré à l'aide des méthodes décrites dans Comment : chiffrer des éléments XML avec des clés asymétriques. Il recherche un élément <EncryptedData>, déchiffre l'élément, puis le remplace par l'élément XML en texte brut d'origine.

Cet exemple déchiffre un élément XML à l'aide de deux clés. Il récupère une clé privée RSA générée précédemment à partir d'un conteneur de clé, puis utilise la clé RSA pour déchiffrer une clé de session stockée dans l'élément <EncryptedKey> de l'élément <EncryptedData>. L'exemple utilise ensuite la clé de session pour déchiffrer l'élément XML.

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 déchiffrer un élément XML avec une clé asymétrique

  1. Créez un objet CspParameters et spécifiez le nom du conteneur de clé.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
    
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
    
  2. Récupérez une clé asymétrique générée précédemment dans le conteneur à l'aide de l'objet RSACryptoServiceProvider. La clé est automatiquement récupérée dans le conteneur de clé lorsque vous passez l'objet CspParameters au constructeur RSACryptoServiceProvider.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Créez un objet EncryptedXml pour déchiffrer le document.

    ' Create a new EncryptedXml object.
    Dim exml As New EncryptedXml(Doc)
    
            // Create a new EncryptedXml object.
            EncryptedXml exml = new EncryptedXml(Doc);
    
  4. Ajoutez un mappage de clé/nom pour associer la clé RSA à l'élément dans le document qui doit être déchiffré. Vous devez utiliser le même nom pour la clé que celui qui vous avez utilisé lorsque vous avez chiffré le document. Remarquez que ce nom est différent du nom utilisé pour identifier la clé dans le conteneur de clé spécifié à l'étape 1.

    exml.AddKeyNameMapping(KeyName, Alg)
    
            exml.AddKeyNameMapping(KeyName, Alg);
    
  5. Appelez la méthode DecryptDocument pour déchiffrer l'élément <EncryptedData>. Cette méthode utilise la clé RSA pour déchiffrer la clé de session et utilise automatiquement la clé de session pour déchiffrer l'élément XML. De plus, elle remplace automatiquement l'élément <EncryptedData> par le texte brut d'origine.

    exml.DecryptDocument()
    
            exml.DecryptDocument();
    
  6. Enregistrez le document XML.

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

Exemple

Imports System
Imports System.Xml
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml



Module Program

    Sub Main(ByVal args() As String)

        ' Create an XmlDocument object.
        Dim xmlDoc As New XmlDocument()

        ' Load an XML file into the XmlDocument object.
        Try
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try
        Dim cspParams As New CspParameters()
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
        ' Get the RSA key from the key container.  This key will decrypt 
        ' a symmetric key that was imbedded in the XML document. 
        Dim rsaKey As New RSACryptoServiceProvider(cspParams)
        Try

            ' Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey")

            ' Save the XML document.
            xmlDoc.Save("test.xml")
            ' Display the encrypted XML to the console.
            Console.WriteLine()
            Console.WriteLine("Decrypted XML:")
            Console.WriteLine()
            Console.WriteLine(xmlDoc.OuterXml)
        Catch e As Exception
            Console.WriteLine(e.Message)
        Finally
            ' Clear the RSA key.
            rsaKey.Clear()
        End Try


        Console.ReadLine()

    End Sub



    Sub Decrypt(ByVal Doc As XmlDocument, ByVal Alg As RSA, ByVal KeyName As String)
        ' 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
        If KeyName Is Nothing Then
            Throw New ArgumentNullException("KeyName")
        End If 
        ' Create a new EncryptedXml object.
        Dim exml As New EncryptedXml(Doc)
        ' Add a key-name mapping.
        ' This method can only decrypt documents
        ' that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg)
        ' Decrypt the element.
        exml.DecryptDocument()
    End Sub
End Module


using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

class Program
{
    static void Main(string[] args)
    {

        // Create an XmlDocument object.
        XmlDocument xmlDoc = new XmlDocument();

        // Load an XML file into the XmlDocument object.
        try
        {
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY";

        // Get the RSA key from the key container.  This key will decrypt
        // a symmetric key that was imbedded in the XML document.
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        try
        {

            // Decrypt the elements.
            Decrypt(xmlDoc, rsaKey, "rsaKey");

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

            // Display the encrypted XML to the console.
            Console.WriteLine();
            Console.WriteLine("Decrypted XML:");
            Console.WriteLine();
            Console.WriteLine(xmlDoc.OuterXml);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Clear the RSA key.
            rsaKey.Clear();
        }


        Console.ReadLine();


    }

    public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
    {
        // Check the arguments.
        if (Doc == null)
            throw new ArgumentNullException("Doc");
        if (Alg == null)
            throw new ArgumentNullException("Alg");
        if (KeyName == null)
            throw new ArgumentNullException("KeyName");
        // Create a new EncryptedXml object.
        EncryptedXml exml = new EncryptedXml(Doc);

        // Add a key-name mapping.
        // This method can only decrypt documents
        // that present the specified key name.
        exml.AddKeyNameMapping(KeyName, Alg);

        // Decrypt the element.
        exml.DecryptDocument();

    }

}

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 XML qui a été chiffré à l'aide des techniques décrites dans Comment : chiffrer des éléments XML avec des clés asymétriques.

Compilation du code

Sécurité

Vous ne devez jamais stocker une clé de chiffrement symétrique en texte brut ou transférer une clé symétrique entre des ordinateurs en texte brut. De plus, vous ne devez jamais stocker ou transférer la clé privée d'une paire de clés asymétrique en texte brut. Pour plus d'informations sur les clés de chiffrement symétriques et asymétriques, consultez Génération de clés pour le chiffrement et le déchiffrement.

N'incorporez jamais directement une clé dans votre code source. Les clés incorporées peuvent être lues facilement à partir d'un assembly à l'aide de l'outil Ildasm.exe (Désassembleur MSIL) ou en ouvrant l'assembly dans un éditeur de texte tel que le Bloc-notes.

Lorsque vous avez fini d'utiliser une clé de chiffrement, effacez-la de la mémoire en affectant la valeur zéro à chaque octet ou en appelant la méthode Clear de la classe de chiffrement managée. Les clés de chiffrement peuvent parfois être lues à partir de la mémoire par un débogueur ou peuvent être lues à partir d'un disque dur si l'emplacement de mémoire est paginé sur le disque.

Voir aussi

Tâches

Comment : chiffrer des éléments XML avec des clés asymétriques

Référence

System.Security.Cryptography.Xml

Autres ressources

Chiffrement XML et signatures numériques

Historique des modifications

Date

Historique

Motif

Juillet 2010

Correction des exemples corrigés erronés.

Commentaires client.