Procédure : déchiffrer des éléments XML avec des clés asymétriques
Vous pouvez utiliser les classes de l'espace de noms System.Security.Cryptography.Xml pour chiffrer et dé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 recommandation du World Wide Web Consortium (W3C)XML Signature Syntax and Processing.
Notes
Le code de cet article s’applique à Windows.
Dans cette procédure, l’exemple 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
>, le déchiffre, 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 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 déchiffrer un élément XML avec une clé asymétrique
Créez un objet CspParameters et spécifiez le nom du conteneur de clé.
CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
Dim cspParams As New CspParameters() cspParams.KeyContainerName = "XML_ENC_RSA_KEY"
Récupérez une clé asymétrique générée précédemment à partir du conteneur à l'aide de l'objet RSACryptoServiceProvider. La clé est automatiquement récupérée depuis le conteneur de clé quand vous passez l'objet CspParameters au constructeur RSACryptoServiceProvider.
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
Dim rsaKey As New RSACryptoServiceProvider(cspParams)
Créez un objet EncryptedXml pour déchiffrer le document.
// Create a new EncryptedXml object. EncryptedXml exml = new EncryptedXml(Doc);
' Create a new EncryptedXml object. Dim exml As New EncryptedXml(Doc)
Ajoutez un mappage nom/clé pour associer la clé RSA à l'élément dans le document qui doit être déchiffré. Vous devez utiliser le même nom de clé que celui que vous avez utilisé quand vous avez chiffré le document. Notez 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)
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. Elle remplace également automatiquement l’élément <EncryptedData
> par le texte brut d’origine.exml.DecryptDocument();
exml.DecryptDocument()
Enregistrez le document XML
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é. Elle 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.
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Runtime.Versioning;
[SupportedOSPlatform("windows")]
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();
}
}
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.
ArgumentNullException.ThrowIfNull(Doc)
ArgumentNullException.ThrowIfNull(Alg)
ArgumentNullException.ThrowIfNull(KeyName)
' 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
Compilation du code
Dans un projet qui cible .NET Framework, incluez une référence à
System.Security.dll
.Dans un projet qui cible .NET Core ou .NET 5, installez le package NuGet System.Security.Cryptography.Xml.
Incluez les espaces de noms suivants : System.Xml, System.Security.Cryptography et System.Security.Cryptography.Xml.
Sécurité .NET
Ne stockez jamais une clé de chiffrement symétrique en texte brut et ne transférez jamais une clé symétrique d'un ordinateur à l'autre en texte brut. De plus, la clé privée d'une paire de clés asymétriques ne doit jamais être stockée ni transférée 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 une clé directement dans votre code source. Les clés incorporées peuvent être lues facilement à partir d’un assembly à l’aide du Désassembleur IL (Ildasm.exe) ou en ouvrant l’assembly dans un éditeur de texte tel que le Bloc-notes.
Quand vous avez terminé d'utiliser une clé de chiffrement, effacez-la de la mémoire en affectant à chaque octet la valeur zéro 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 à partir d'un disque dur si l'emplacement de mémoire est paginé sur le disque.