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).
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
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)
Ouvrez le magasin en lecture seule.
store.Open(OpenFlags.ReadOnly);
store.Open(OpenFlags.ReadOnly)
Initialisez un X509Certificate2Collection avec tous les certificats du magasin.
X509Certificate2Collection certCollection = store.Certificates;
Dim certCollection As X509Certificate2Collection = store.Certificates
É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
Quand vous avez trouvé le certificat, fermez le magasin.
store.Close();
store.Close()
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()
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)
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)
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)
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
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
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
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour