SignedXml Classe
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Fournit un wrapper sur un objet de signature XML principal pour faciliter la création de signatures XML.
public ref class SignedXml
public class SignedXml
type SignedXml = class
Public Class SignedXml
- Héritage
-
SignedXml
Exemples
L’exemple de code suivant montre comment signer et vérifier un document XML entier à l’aide d’une signature enveloppe.
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
try
{
// Generate a signing key.
RSA Key = RSA.Create();
// Create an XML file to sign.
CreateSomeXml("Example.xml");
Console.WriteLine("New XML file created.");
// Sign the XML that was just created and save it in a
// new file.
SignXmlFile("Example.xml", "signedExample.xml", Key);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml", Key);
// Display the results of the signature verification to
// the console.
if(result)
{
Console.WriteLine("The XML signature is valid.");
}
else
{
Console.WriteLine("The XML signature is not valid.");
}
}
catch(CryptographicException e)
{
Console.WriteLine(e.Message);
}
}
// Sign an XML file and save the signature in a new file. This method does not
// save the public key within the XML file. This file cannot be verified unless
// the verifying code has the key with which it was signed.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key)
{
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Load the passed XML file using its name.
doc.Load(new XmlTextReader(FileName));
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file against an asymmetric
// algorithm and return the result.
public static Boolean VerifyXmlFile(String Name, RSA Key)
{
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
// Create example data to sign.
public static void CreateSomeXml(string FileName)
{
// Create a new XmlDocument object.
XmlDocument document = new XmlDocument();
// Create a new XmlNode object.
XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples");
// Add some text to the node.
node.InnerText = "Example text to be signed.";
// Append the node to the document.
document.AppendChild(node);
// Save the XML document to the file name specified.
XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false));
document.WriteTo(xmltw);
xmltw.Close();
}
}
'
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Public Class SignVerifyEnvelope
Overloads Public Shared Sub Main(args() As [String])
Try
' Generate a signing key.
Dim Key As RSA = RSA.Create()
' Create an XML file to sign.
CreateSomeXml("Example.xml")
Console.WriteLine("New XML file created.")
' Sign the XML that was just created and save it in a
' new file.
SignXmlFile("Example.xml", "signedExample.xml", Key)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml", Key)
' Display the results of the signature verification to
' the console.
If result Then
Console.WriteLine("The XML signature is valid.")
Else
Console.WriteLine("The XML signature is not valid.")
End If
Catch e As CryptographicException
Console.WriteLine(e.Message)
End Try
End Sub
' Sign an XML file and save the signature in a new file. This method does not
' save the public key within the XML file. This file cannot be verified unless
' the verifying code has the key with which it was signed.
Public Shared Sub SignXmlFile(FileName As String, SignedFileName As String, Key As RSA)
' Create a new XML document.
Dim doc As New XmlDocument()
' Load the passed XML file using its name.
doc.Load(New XmlTextReader(FileName))
' Create a SignedXml object.
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
signedXml.SigningKey = Key
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = ""
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
' Compute the signature.
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file against an asymmetric
' algorithm and return the result.
Public Shared Function VerifyXmlFile(Name As [String], Key As RSA) As [Boolean]
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature(Key)
End Function
' Create example data to sign.
Public Shared Sub CreateSomeXml(FileName As String)
' Create a new XmlDocument object.
Dim document As New XmlDocument()
' Create a new XmlNode object.
Dim node As XmlNode = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples")
' Add some text to the node.
node.InnerText = "Example text to be signed."
' Append the node to the document.
document.AppendChild(node)
' Save the XML document to the file name specified.
Dim xmltw As New XmlTextWriter(FileName, New UTF8Encoding(False))
document.WriteTo(xmltw)
xmltw.Close()
End Sub
End Class
L’exemple de code suivant montre comment signer et vérifier un élément unique d’un document XML à l’aide d’une signature enveling.
//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
public class SignVerifyEnvelope
{
public static void Main(String[] args)
{
// Generate a signing key.
RSA Key = RSA.Create();
try
{
// Specify an element to sign.
string[] elements = { "#tag1" };
// Sign an XML file and save the signature to a
// new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements);
Console.WriteLine("XML file signed.");
// Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...");
bool result = VerifyXmlFile("SignedExample.xml");
// Display the results of the signature verification to
// the console.
if (result)
{
Console.WriteLine("The XML signature is valid.");
}
else
{
Console.WriteLine("The XML signature is not valid.");
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
finally
{
// Clear resources associated with the
// RSA instance.
Key.Clear();
}
}
// Sign an XML file and save the signature in a new file.
public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign)
{
// Check the arguments.
if (FileName == null)
throw new ArgumentNullException("FileName");
if (SignedFileName == null)
throw new ArgumentNullException("SignedFileName");
if (Key == null)
throw new ArgumentNullException("Key");
if (ElementsToSign == null)
throw new ArgumentNullException("ElementsToSign");
// Create a new XML document.
XmlDocument doc = new XmlDocument();
// Format the document to ignore white spaces.
doc.PreserveWhitespace = false;
// Load the passed XML file using it's name.
doc.Load(new XmlTextReader(FileName));
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Loop through each passed element to sign
// and create a reference.
foreach (string s in ElementsToSign)
{
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = s;
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
}
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue((RSA)Key));
signedXml.KeyInfo = keyInfo;
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
if (doc.FirstChild is XmlDeclaration)
{
doc.RemoveChild(doc.FirstChild);
}
// Save the signed XML document to a file specified
// using the passed string.
XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
doc.WriteTo(xmltw);
xmltw.Close();
}
// Verify the signature of an XML file and return the result.
public static Boolean VerifyXmlFile(String Name)
{
// Check the arguments.
if (Name == null)
throw new ArgumentNullException("Name");
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
// Format using white spaces.
xmlDocument.PreserveWhitespace = true;
// Load the passed XML file into the document.
xmlDocument.Load(Name);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature();
}
}
' This example signs an XML file using an
' envelope signature. It then verifies the
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Module SignVerifyEnvelope
Sub Main(ByVal args() As String)
' Generate a signing key.
Dim Key As RSA = RSA.Create()
Try
' Specify an element to sign.
Dim elements As String() = New String() {"#tag1"}
' Sign an XML file and save the signature to a
' new file.
SignXmlFile("Test.xml", "SignedExample.xml", Key, elements)
Console.WriteLine("XML file signed.")
' Verify the signature of the signed XML.
Console.WriteLine("Verifying signature...")
Dim result As Boolean = VerifyXmlFile("SignedExample.xml")
' Display the results of the signature verification to \
' the console.
If result Then
Console.WriteLine("The XML signature is valid.")
Else
Console.WriteLine("The XML signature is not valid.")
End If
Catch e As CryptographicException
Console.WriteLine(e.Message)
Finally
' Clear resources associated with the
' RSA instance.
Key.Clear()
End Try
End Sub
' Sign an XML file and save the signature in a new file.
Sub SignXmlFile(ByVal FileName As String, ByVal SignedFileName As String, ByVal Key As RSA, ByVal ElementsToSign() As String)
' Check the arguments.
If FileName Is Nothing Then
Throw New ArgumentNullException("FileName")
End If
If SignedFileName Is Nothing Then
Throw New ArgumentNullException("SignedFileName")
End If
If Key Is Nothing Then
Throw New ArgumentNullException("Key")
End If
If ElementsToSign Is Nothing Then
Throw New ArgumentNullException("ElementsToSign")
End If
' Create a new XML document.
Dim doc As New XmlDocument()
' Format the document to ignore white spaces.
doc.PreserveWhitespace = False
' Load the passed XML file using it's name.
doc.Load(New XmlTextReader(FileName))
' Create a SignedXml object.
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
signedXml.SigningKey = Key
' Loop through each passed element to sign
' and create a reference.
Dim s As String
For Each s In ElementsToSign
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = s
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
Next s
' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
Dim keyInfo As New KeyInfo()
keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
signedXml.KeyInfo = keyInfo
' Compute the signature.
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Save the signed XML document to a file specified
' using the passed string.
Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
doc.WriteTo(xmltw)
xmltw.Close()
End Sub
' Verify the signature of an XML file and return the result.
Function VerifyXmlFile(ByVal Name As String) As [Boolean]
' Check the arguments.
If Name Is Nothing Then
Throw New ArgumentNullException("Name")
End If
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Format using white spaces.
xmlDocument.PreserveWhitespace = True
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature()
End Function
End Module
Remarques
La SignedXml classe est l’implémentation .NET de la syntaxe et du traitement de signature XML W3C (World Wide Web Consortium), également appelée XMLDSIG (signature numérique XML). XMLDSIG est un moyen basé sur des normes et interopérable de signer et de vérifier tout ou partie d’un document XML ou d’autres données adressables à partir d’un URI (Uniform Resource Identifier).
Utilisez la SignedXml classe chaque fois que vous devez partager des données XML signées entre des applications ou des organisations de manière standard. Toutes les données signées à l’aide de cette classe peuvent être vérifiées par toute implémentation conforme de la spécification W3C pour XMLDSIG.
La SignedXml classe vous permet de créer les trois types de signatures numériques XML suivantes :
| Type de signature | Description |
|---|---|
| Signature enveloppée | La signature est contenue dans l’élément XML en cours de signature. |
| Signature enveloppante | Le code XML signé est contenu dans l’élément <Signature> . |
| Signature détachée interne | La signature et le code XML signé se trouvent dans le même document, mais aucun élément ne contient l’autre. |
Il existe également un quatrième type de signature appelé signature détachée externe, c’est-à-dire lorsque les données et la signature se trouvent dans des documents XML distincts. Les signatures détachées externes ne sont pas prises en charge par la SignedXml classe.
Structure d’une signature XML
XMLDSIG crée un <Signature> élément, qui contient une signature numérique d’un document XML ou d’autres données adressables à partir d’un URI. L’élément <Signature> peut éventuellement contenir des informations sur l’emplacement où trouver une clé qui vérifie la signature et l’algorithme de chiffrement utilisé pour la signature. La structure de base est la suivante :
<Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Base64EncodedValue==</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>AnotherBase64EncodedValue===</SignatureValue>
</Signature>
Les principales parties de cette structure sont les suivantes :
Élément
<CanonicalizationMethod>Spécifie les règles de réécriture de l’élément
Signatureà partir de XML/text en octets pour la validation de signature. La valeur par défaut dans .NET est http://www.w3.org/TR/2001/REC-xml-c14n-20010315, qui identifie un algorithme fiable. Cet élément est représenté par la SignedInfo.CanonicalizationMethod propriété.Élément
<SignatureMethod>Spécifie l’algorithme utilisé pour la génération et la validation de signature, qui a été appliqué à l’élément
<Signature>pour produire la valeur dans<SignatureValue>. Dans l’exemple précédent, la valeur http://www.w3.org/2000/09/xmldsig#rsa-sha1 identifie une signature SHA-1 RSA PKCS1. En raison de problèmes de collision avec SHA-1, Microsoft recommande un modèle de sécurité basé sur SHA-256 ou mieux. Cet élément est représenté par la SignatureMethod propriété.Élément
<SignatureValue>Spécifie la signature de chiffrement de l’élément
<Signature>. Si cette signature ne vérifie pas, une partie du<Signature>bloc a été falsifiée et le document est considéré comme non valide. Tant que la<CanonicalizationMethod>valeur est fiable, cette valeur est hautement résistante à la falsification. Cet élément est représenté par la SignatureValue propriété.Attribut
URIde l’élément<Reference>Spécifie un objet de données à l’aide d’une référence d’URI. Cet attribut est représenté par la Reference.Uri propriété.
Ne pas spécifier l’attribut
URI, autrement dit, définir la propriété Reference.Uri ànull, signifie que l’application de réception est censée connaître l’identité de l’objet. Dans la plupart des cas, unnullURI entraîne la levée d’une exception. N’utilisez pas d’URInull, sauf si votre application interopérait avec un protocole qui l’exige.La définition de l’attribut
URIsur une chaîne vide indique que l’élément racine du document est signé, une forme de signature enveloppe.Si la valeur de l’attribut
URIcommence par #, la valeur doit être résolue en un élément du document actif. Ce formulaire peut être utilisé avec n’importe quel type de signature pris en charge (signature enveloppée, signature enveloppante ou signature détachée interne).Tout autre élément est considéré comme une signature détachée de ressource externe et n’est pas pris en charge par la SignedXml classe.
Élément
<Transforms>Contient une liste ordonnée d’éléments
<Transform>qui décrivent comment le signataire a obtenu l’objet de données qui a été digesté. Un algorithme de transformation est similaire à la méthode de canonisation, mais au lieu de réécrire l’élément<Signature>, il réécrit le contenu identifié par l’attributURIde l’élément<Reference>. L’élément<Transforms>est représenté par la TransformChain classe.Chaque algorithme de transformation est défini comme prenant xml (un jeu de nœuds XPath) ou des octets comme entrée. Si le format des données actuelles diffère des exigences d’entrée de transformation, les règles de conversion sont appliquées.
Chaque algorithme de transformation est défini comme produisant du code XML ou des octets comme sortie.
Si la sortie du dernier algorithme de transformation n’est pas définie en octets (ou si aucune transformation n’a été spécifiée), la méthode de canonisation est utilisée comme transformation implicite (même si un autre algorithme a été spécifié dans l’élément
<CanonicalizationMethod>).Une valeur de l’algorithme de http://www.w3.org/2000/09/xmldsig#enveloped-signature transformation encode une règle interprétée comme supprimant l’élément
<Signature>du document. Dans le cas contraire, un vérificateur d'une signature enveloppée hachera le document, y compris la signature, mais le signataire aurait haché le document avant que la signature ne soit appliquée, ce qui entraîne des réponses différentes.
Élément
<DigestMethod>Identifie la méthode digest (hachage de chiffrement) à appliquer sur le contenu transformé identifié par l’attribut
URIde l’élément<Reference>. Ceci est représenté par la Reference.DigestMethod propriété.
Choix d’une méthode de canonisation
À moins d’interagir avec une spécification qui nécessite l’utilisation d’une valeur différente, nous vous recommandons d’utiliser la méthode de canonisation .NET par défaut, qui est l’algorithme XML-C14N 1.0, dont la valeur est http://www.w3.org/TR/2001/REC-xml-c14n-20010315. L’algorithme XML-C14N 1.0 doit être pris en charge par toutes les implémentations de XMLDSIG, en particulier lorsqu’il s’agit d’une transformation finale implicite à appliquer.
Il existe des versions d’algorithmes de canonisation qui prennent en charge la conservation des commentaires. Les méthodes de canonisation préservant les commentaires ne sont pas recommandées, car elles violent le principe de « signer ce qui est vu ». Autrement dit, les commentaires d’un <Signature> élément ne modifient pas la logique de traitement pour la façon dont la signature est effectuée, simplement ce que la valeur de signature est. Lorsqu’ils sont combinés avec un algorithme de signature faible, ce qui permet aux commentaires d’être inclus donne à un attaquant une liberté inutile de forcer une collision de hachage, ce qui rend un document falsifié légitime. Dans .NET Framework, seuls les canoniques intégrés sont pris en charge par défaut. Pour prendre en charge des canonicalisateurs supplémentaires ou personnalisés, consultez la propriété SafeCanonicalizationMethods. Si le document utilise une méthode de canonisation qui n’est pas dans la collection représentée par la SafeCanonicalizationMethods propriété, la CheckSignature méthode retourne false.
Note
Une application extrêmement défensive peut supprimer toutes les valeurs qu’elle ne s’attend pas à ce que les signataires utilisent de la SafeCanonicalizationMethods collection.
Les valeurs de référence ne peuvent-elles pas être falsifiées ?
Oui, les <Reference> valeurs ne sont pas falsifiées. .NET vérifie le <SignatureValue> calcul avant de traiter l’une <Reference> des valeurs et leurs transformations associées, et abandonne tôt pour éviter les instructions de traitement potentiellement malveillantes.
Choisir les éléments à signer
Nous vous recommandons d’utiliser la valeur « » pour l’attribut URI (ou de définir la Uri propriété sur une chaîne vide), si possible. Cela signifie que l’ensemble du document est pris en compte pour le calcul de synthèse, ce qui signifie que l’ensemble du document est protégé contre la falsification.
Il est très courant de voir URI les valeurs sous la forme d’ancres telles que #foo, faisant référence à un élément dont l’attribut ID est « foo ». Malheureusement, il est facile d’être falsifié car cela inclut uniquement le contenu de l’élément cible, et non le contexte. L’abus de cette distinction est connu sous le nom d’habillage de signature XML (XSW).
Si votre application considère que les commentaires sont sémantiques (ce qui n’est pas courant lorsque vous traitez avec XML), vous devez utiliser « #xpointer(/) » au lieu de « » et « #xpointer(id('foo')) » au lieu de « #foo ». Les versions #xpointer sont interprétées comme incluant des commentaires, tandis que les formulaires de nom court excluent les commentaires.
Si vous devez accepter des documents qui ne sont que partiellement protégés et que vous souhaitez vous assurer que vous lisez le même contenu que celui protégé par la signature, utilisez la GetIdElement méthode.
Considérations relatives à la sécurité relatives à l’élément KeyInfo
Les données de l’élément facultatif <KeyInfo> (autrement dit, la KeyInfo propriété), qui contient une clé pour valider la signature, ne doivent pas être approuvées.
En particulier, lorsque la KeyInfo valeur représente une clé publique RSA, DSA ou ECDSA nue, le document a pu être falsifié, malgré la CheckSignature méthode signalant que la signature est valide. Cela peut se produire, car l’entité qui effectue la falsification doit simplement générer une nouvelle clé et signer à nouveau le document falsifié avec cette nouvelle clé. Par conséquent, sauf si votre application vérifie que la clé publique est une valeur attendue, le document doit être traité comme s’il a été falsifié. Cela nécessite que votre application examine la clé publique incorporée dans le document et la vérifie sur une liste de valeurs connues pour le contexte du document. Par exemple, si le document peut être compris pour être émis par un utilisateur connu, vous devez vérifier la clé par rapport à une liste de clés connues utilisées par cet utilisateur.
Vous pouvez également vérifier la clé après avoir traité le document à l’aide de la CheckSignatureReturningKey méthode, au lieu d’utiliser la CheckSignature méthode. Toutefois, pour une sécurité optimale, vous devez vérifier la clé au préalable.
En alternative, envisagez d'essayer les clés publiques enregistrées de l'utilisateur, plutôt que de lire ce qui se trouve dans l'élément <KeyInfo>.
Considérations relatives à la sécurité relatives à l’élément X509Data
L’élément facultatif <X509Data> est un enfant de l’élément <KeyInfo> et contient un ou plusieurs certificats ou identificateurs X509 pour les certificats X509. Les données de l’élément <X509Data> ne doivent pas non plus être intrinsèquement approuvées.
Lors de la vérification d’un document avec l’élément incorporé <X509Data> , .NET vérifie uniquement que les données sont résolues sur un certificat X509 dont la clé publique peut être utilisée avec succès pour valider la signature du document. Contrairement à l’appel de la CheckSignature méthode avec le paramètre verifySignatureOnly défini sur false, aucune vérification de révocation n’est effectuée, aucune chaîne de confiance n’est vérifiée et l’expiration n’est pas vérifiée. Même si votre application extrait le certificat lui-même et le transmet à la méthode CheckSignature avec le paramètre verifySignatureOnly défini sur false, cela n’est toujours pas une validation suffisante pour empêcher la falsification de document. Le certificat doit toujours être vérifié comme approprié pour le document signé.
L’utilisation d’un certificat de signature incorporé peut fournir des stratégies de rotation de clés utiles, que ce soit dans la <X509Data> section ou dans le contenu du document. Lorsque vous utilisez cette approche, une application doit extraire le certificat manuellement et effectuer une validation similaire à :
Le certificat a été émis directement ou via une chaîne par une autorité de certification dont le certificat public est incorporé dans l’application.
L’utilisation de la liste de confiance fournie par le système d’exploitation sans vérification supplémentaire, telle qu’un nom de sujet connu, n’est pas suffisante pour empêcher la falsification dans SignedXml.
Le certificat est vérifié qu’il n’a pas été expiré au moment de la signature de document (ou « maintenant » pour le traitement de documents en quasi temps réel).
Pour les certificats de longue durée émis par une autorité de certification qui prend en charge la révocation, vérifiez que le certificat n’a pas été révoqué.
L’objet du certificat est vérifié comme approprié pour le document actuel.
Choix de l’algorithme de transformation
Si vous interagissez avec une spécification qui a dicté des valeurs spécifiques (telles que XrML), vous devez suivre la spécification. Si vous avez une signature enveloppe (par exemple, lors de la signature de l’ensemble du document), vous devez utiliser http://www.w3.org/2000/09/xmldsig#enveloped-signature (représentée par la XmlDsigEnvelopedSignatureTransform classe). Vous pouvez également spécifier la transformation de XML-C14N implicite, mais elle n’est pas nécessaire. Pour une signature enveloppante ou détachée, aucune transformation n’est requise. La transformation implicite XML-C14N prend en charge tout.
Avec la mise à jour de sécurité introduite par le bulletin Sécurité Microsoft MS16-035, .NET restreint les transformations qui peuvent être utilisées dans la vérification de document par défaut. Les transformations non approuvées provoquent CheckSignature toujours un retour false. En particulier, les transformations qui nécessitent une entrée supplémentaire (spécifiées en tant qu’éléments enfants dans le CODE XML) ne sont pas autorisées en raison de leur sensibilité à l’abus par des utilisateurs malveillants. Le W3C conseille d’éviter les transformations XPath et XSLT, qui sont les deux transformations principales affectées par ces restrictions.
Le problème avec les références externes
Si une application ne vérifie pas que les références externes semblent appropriées pour le contexte actuel, elles peuvent être abusées de manière à fournir de nombreuses vulnérabilités de sécurité (y compris déni de service, déni de service distribué, divulgation d’informations, contournement de signature et exécution de code distant). Même si une application devait valider l’URI de référence externe, il y aurait un problème de chargement de la ressource deux fois : une fois lorsque votre application l’a lue et une fois lors SignedXml de sa lecture. Étant donné qu’il n’existe aucune garantie que les étapes de lecture et de vérification des documents de l’application ont le même contenu, la signature ne fournit pas de fiabilité.
Compte tenu des risques liés aux références externes, SignedXml lève une exception lorsqu’une référence externe est rencontrée. Pour plus d’informations sur ce problème, consultez .NET applications rencontrent des erreurs d’exception.
Constructeurs
| Nom | Description |
|---|---|
| SignedXml() |
Initialise une nouvelle instance de la classe SignedXml. |
| SignedXml(XmlDocument) |
Initialise une nouvelle instance de la SignedXml classe à partir du document XML spécifié. |
| SignedXml(XmlElement) |
Initialise une nouvelle instance de la SignedXml classe à partir de l’objet spécifié XmlElement . |
Champs
| Nom | Description |
|---|---|
| m_signature | |
| m_strSigningKeyName |
Représente le nom de la clé installée à utiliser pour signer l’objet SignedXml . |
| XmlDecryptionTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la transformation de déchiffrement du mode XML. Ce champ est constant. |
| XmlDsigBase64TransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la transformation de base 64. Ce champ est constant. |
| XmlDsigC14NTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la transformation XML canonique. Ce champ est constant. |
| XmlDsigC14NWithCommentsTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la transformation XML canonique, avec des commentaires. Ce champ est constant. |
| XmlDsigCanonicalizationUrl |
Représente l’URI (Uniform Resource Identifier) pour l’algorithme de canonisation standard pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigCanonicalizationWithCommentsUrl |
Représente l’URI (Uniform Resource Identifier) pour l’algorithme de canonique standard pour les signatures numériques XML et inclut des commentaires. Ce champ est constant. |
| XmlDsigDSAUrl |
Représente l’URI (Uniform Resource Identifier) de l’algorithme standard DSA pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigEnvelopedSignatureTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la transformation de signature enveloppe. Ce champ est constant. |
| XmlDsigExcC14NTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la canonisation XML exclusive. Ce champ est constant. |
| XmlDsigExcC14NWithCommentsTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour la canonisation XML exclusive, avec des commentaires. Ce champ est constant. |
| XmlDsigHMACSHA1Url |
Représente l’URI (Uniform Resource Identifier) de l’algorithme standard HMACSHA1 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigMinimalCanonicalizationUrl |
Représente l’URI (Uniform Resource Identifier) pour l’algorithme de canonisation minimal standard pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigNamespaceUrl |
Représente l’URI (Uniform Resource Identifier) de l’espace de noms standard pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigRSASHA1Url |
Représente l’URI (Uniform Resource Identifier) pour la méthode de signature standard RSA pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigRSASHA256Url |
Représente l’URI (Uniform Resource Identifier) pour la RSA variante de méthode de signature SHA-256 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigRSASHA384Url |
Représente l’URI (Uniform Resource Identifier) pour la RSA variante de méthode de signature SHA-384 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigRSASHA512Url |
Représente l’URI (Uniform Resource Identifier) pour la RSA variante de méthode de signature SHA-512 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigSHA1Url |
Représente l’URI (Uniform Resource Identifier) pour la méthode digest standard SHA1 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigSHA256Url |
Représente l’URI (Uniform Resource Identifier) pour la méthode digest standard SHA256 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigSHA384Url |
Représente l’URI (Uniform Resource Identifier) pour la méthode digest standard SHA384 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigSHA512Url |
Représente l’URI (Uniform Resource Identifier) pour la méthode digest standard SHA512 pour les signatures numériques XML. Ce champ est constant. |
| XmlDsigXPathTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour le langage XPath (XML Path Language). Ce champ est constant. |
| XmlDsigXsltTransformUrl |
Représente l’URI (Uniform Resource Identifier) pour les transformations XSLT. Ce champ est constant. |
| XmlLicenseTransformUrl |
Représente l’URI (Uniform Resource Identifier) de l’algorithme de transformation de licence utilisé pour normaliser les licences XrML pour les signatures. |
Propriétés
| Nom | Description |
|---|---|
| EncryptedXml |
Obtient ou définit un EncryptedXml objet qui définit les règles de traitement du chiffrement XML. |
| KeyInfo |
Obtient ou définit l’objet KeyInfo de l’objet actuel SignedXml . |
| Resolver |
Définit l’objet actuel XmlResolver . |
| SafeCanonicalizationMethods |
Obtient les noms des méthodes dont les algorithmes de canonisation sont explicitement autorisés. |
| Signature | |
| SignatureFormatValidator |
Obtient un délégué qui sera appelé pour valider le format (et non la sécurité de chiffrement) d’une signature XML. |
| SignatureLength |
Obtient la longueur de la signature de l’objet actif SignedXml . |
| SignatureMethod |
Obtient la méthode de signature de l’objet actuel SignedXml . |
| SignatureValue |
Obtient la valeur de signature de l’objet actuel SignedXml . |
| SignedInfo |
Obtient l’objet SignedInfo de l’objet actif SignedXml . |
| SigningKey |
Obtient ou définit la clé d’algorithme asymétrique utilisée pour signer un SignedXml objet. |
| SigningKeyName |
Obtient ou définit le nom de la clé installée à utiliser pour signer l’objet SignedXml . |
Méthodes
| Nom | Description |
|---|---|
| AddObject(DataObject) |
Ajoute un DataObject objet à la liste des objets à signer. |
| AddReference(Reference) |
Ajoute un Reference objet à l’objet SignedXml qui décrit une méthode digest, une valeur digest et une transformation à utiliser pour créer une signature numérique XML. |
| CheckSignature() |
Détermine si la Signature propriété vérifie à l’aide de la clé publique dans la signature. |
| CheckSignature(AsymmetricAlgorithm) |
Détermine si la Signature propriété vérifie pour la clé spécifiée. |
| CheckSignature(KeyedHashAlgorithm) |
Détermine si la Signature propriété vérifie pour l’algorithme MAC (Message Authentication Code) spécifié. |
| CheckSignature(X509Certificate2, Boolean) |
Détermine si la Signature propriété vérifie pour l’objet spécifié X509Certificate2 et, éventuellement, si le certificat est valide. |
| CheckSignatureReturningKey(AsymmetricAlgorithm) |
Détermine si la Signature propriété vérifie à l’aide de la clé publique dans la signature. |
| ComputeSignature() |
Calcule une signature numérique XML. |
| ComputeSignature(KeyedHashAlgorithm) |
Calcule une signature numérique XML à l’aide de l’algorithme MAC (Message Authentication Code) spécifié. |
| Equals(Object) |
Détermine si l’objet spécifié est égal à l’objet actuel. (Hérité de Object) |
| GetHashCode() |
Sert de fonction de hachage par défaut. (Hérité de Object) |
| GetIdElement(XmlDocument, String) |
Retourne l’objet XmlElement avec l’ID spécifié de l’objet spécifié XmlDocument . |
| GetPublicKey() |
Retourne la clé publique d’une signature. |
| GetType() |
Obtient la Type de l’instance actuelle. (Hérité de Object) |
| GetXml() |
Retourne la représentation XML d’un SignedXml objet. |
| LoadXml(XmlElement) |
Charge un SignedXml état à partir d’un élément XML. |
| MemberwiseClone() |
Crée une copie superficielle du Objectactuel. (Hérité de Object) |
| ToString() |
Retourne une chaîne qui représente l’objet actuel. (Hérité de Object) |