SignedXml Klas

Definitie

Biedt een wrapper op een basis-XML-handtekeningobject om het maken van XML-handtekeningen te vergemakkelijken.

public ref class SignedXml
public class SignedXml
type SignedXml = class
Public Class SignedXml
Overname
SignedXml

Voorbeelden

In het volgende codevoorbeeld ziet u hoe u een volledig XML-document kunt ondertekenen en verifiëren met behulp van een envelophandtekening.

//
// 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

In het volgende codevoorbeeld ziet u hoe u één element van een XML-document ondertekent en verifieert met behulp van een enveloppenhandtekening.

//
// 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

Opmerkingen

De SignedXml klasse is de .NET-implementatie van het World Wide Web Consortium (W3C) XML Signature Syntax and Processing Specification, ook wel bekend als XMLDSIG (XML Digital Signature). XMLDSIG is een op standaarden gebaseerde, interoperabele manier om alle of een deel van een XML-document of andere gegevens te ondertekenen en te verifiëren die kunnen worden adresseerbaar vanuit een URI (Uniform Resource Identifier).

Gebruik de SignedXml klasse wanneer u ondertekende XML-gegevens wilt delen tussen toepassingen of organisaties op een standaard manier. Alle gegevens die met deze klasse zijn ondertekend, kunnen worden geverifieerd door elke conforme implementatie van de W3C-specificatie voor XMLDSIG.

Met SignedXml de klasse kunt u de volgende drie soorten DIGITALE XML-handtekeningen maken:

Handtekeningtype Description
Handtekening met envelop De handtekening bevindt zich in het XML-element dat wordt ondertekend.
Omsluitende handtekening De ondertekende XML bevindt zich in het <Signature> element.
Interne losgekoppelde handtekening De handtekening en de ondertekende XML bevinden zich in hetzelfde document, maar geen van beide elementen bevat het andere element.

Er is ook een vierde soort handtekening, een externe, losgekoppelde handtekening, namelijk wanneer de gegevens en handtekening zich in afzonderlijke XML-documenten bevinden. Externe losgekoppelde handtekeningen worden niet ondersteund door de SignedXml klasse.

Structuur van een XML-handtekening

XMLDSIG maakt een <Signature> element dat een digitale handtekening bevat van een XML-document of andere gegevens die kunnen worden adresseerbaar vanuit een URI. Het <Signature> element kan eventueel informatie bevatten over waar u een sleutel kunt vinden die de handtekening verifieert en welk cryptografisch algoritme is gebruikt voor ondertekening. De basisstructuur is als volgt:

<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>

De belangrijkste onderdelen van deze structuur zijn:

  • Het <CanonicalizationMethod> element

    Hiermee geeft u de regels voor het herschrijven van het Signature element van XML/tekst in bytes voor handtekeningvalidatie. De standaardwaarde in .NET is http://www.w3.org/TR/2001/REC-xml-c14n-20010315, waarmee een betrouwbaar algoritme wordt geïdentificeerd. Dit element wordt vertegenwoordigd door de SignedInfo.CanonicalizationMethod eigenschap.

  • Het <SignatureMethod> element

    Hiermee geeft u het algoritme op dat wordt gebruikt voor het genereren en valideren van handtekeningen, die is toegepast op het <Signature> element om de waarde in <SignatureValue>te produceren. In het vorige voorbeeld identificeert de waarde http://www.w3.org/2000/09/xmldsig#rsa-sha1 een RSA PKCS1 SHA-1-handtekening. Vanwege conflictproblemen met SHA-1 raadt Microsoft een beveiligingsmodel aan op basis van SHA-256 of beter. Dit element wordt vertegenwoordigd door de SignatureMethod eigenschap.

  • Het <SignatureValue> element

    Hiermee geeft u de cryptografische handtekening voor het <Signature> element. Als deze handtekening niet controleert, is er met een deel van het <Signature> blok geknoeid en wordt het document als ongeldig beschouwd. Zolang de <CanonicalizationMethod> waarde betrouwbaar is, is deze waarde zeer bestand tegen manipulatie. Dit element wordt vertegenwoordigd door de SignatureValue eigenschap.

  • Het URI kenmerk van het <Reference> element

    Hiermee geeft u een gegevensobject op met behulp van een URI-verwijzing. Dit kenmerk wordt vertegenwoordigd door de Reference.Uri eigenschap.

    • Als u het URI kenmerk niet opgeeft, betekent dit dat de Reference.Urinullontvangende toepassing naar verwachting de identiteit van het object kent. In de meeste gevallen leidt een null URI ertoe dat er een uitzondering wordt gegenereerd. Gebruik geen null URI, tenzij uw toepassing werkt met een protocol dat dit vereist.

    • Als u het URI kenmerk instelt op een lege tekenreeks, wordt aangegeven dat het hoofdelement van het document wordt ondertekend, een vorm van een envelophandtekening.

    • Als de waarde van URI het kenmerk begint met #, moet de waarde worden omgezet in een element in het huidige document. Dit formulier kan worden gebruikt met een van de ondersteunde handtekeningtypen (envelophandtekening, envelophandtekening of interne losgekoppelde handtekening).

    • Iets anders wordt beschouwd als een handtekening voor externe resources die is losgekoppeld en wordt niet ondersteund door de SignedXml klasse.

  • Het <Transforms> element

    Bevat een geordende lijst <Transform> met elementen die beschrijven hoe de ondertekenaar het gegevensobject heeft verkregen dat is verwerkt. Een transformatiealgoritme is vergelijkbaar met de canonicalisatiemethode, maar in plaats van het <Signature> element te herschrijven, herschrijft het de inhoud die wordt geïdentificeerd door het URI kenmerk van het <Reference> element. Het <Transforms> element wordt vertegenwoordigd door de TransformChain klasse.

    • Elk transformatie-algoritme wordt gedefinieerd als het nemen van XML (een XPath-knooppuntset) of bytes als invoer. Als de indeling van de huidige gegevens verschilt van de invoervereisten voor transformatie, worden conversieregels toegepast.

    • Elk transformatie-algoritme wordt gedefinieerd als het opleveren van XML of bytes als uitvoer.

    • Als de uitvoer van het laatste transformatie-algoritme niet is gedefinieerd in bytes (of er zijn geen transformaties opgegeven), wordt de canonicalisatiemethode gebruikt als een impliciete transformatie (zelfs als er een ander algoritme is opgegeven in het <CanonicalizationMethod> element).

    • Een waarde van http://www.w3.org/2000/09/xmldsig#enveloped-signature het transformatiealgoritmen codeert een regel die wordt geïnterpreteerd als het <Signature> element uit het document verwijderen. Anders zal een verificator van een omhulde handtekening het document verwerken, inclusief de handtekening, maar de ondertekenaar zou het document hebben verwerkt voordat de handtekening werd toegepast, wat leidt tot verschillende resultaten.

  • Het <DigestMethod> element

    Identificeert de digest-methode (cryptografische hash) die moet worden toegepast op de getransformeerde inhoud die wordt geïdentificeerd door het URI kenmerk van het <Reference> element. Dit wordt vertegenwoordigd door de Reference.DigestMethod eigenschap.

Een canonicalisatiemethode kiezen

Tenzij er samenwerking is met een specificatie waarvoor het gebruik van een andere waarde is vereist, raden we u aan de standaard .NET canonicalization-methode te gebruiken. Dit is het XML-C14N 1.0-algoritme, waarvan de waarde is http://www.w3.org/TR/2001/REC-xml-c14n-20010315. Het algoritme XML-C14N 1.0 moet worden ondersteund door alle implementaties van XMLDSIG, met name omdat het een impliciete definitieve transformatie is die moet worden toegepast.

Er zijn versies van canonicalisatiealgoritmen die ondersteuning bieden voor het behouden van opmerkingen. Canonicalisatiemethoden die opmerkingen behouden, worden niet aanbevolen omdat ze het principe 'teken wat wordt gezien' schenden. Dat wil zeggen dat de opmerkingen in een <Signature> element de verwerkingslogica niet wijzigen voor de manier waarop de handtekening wordt uitgevoerd, alleen wat de handtekeningwaarde is. In combinatie met een zwak algoritme voor handtekeningen, waarbij opmerkingen kunnen worden toegevoegd, krijgt een aanvaller onnodige vrijheid om een hashcollision te forceren, waardoor een gemanipuleerd document legitiem lijkt. In .NET Framework worden standaard alleen ingebouwde canonicalizers ondersteund. Zie de SafeCanonicalizationMethods eigenschap als u aanvullende of aangepaste canonicalizers wilt ondersteunen. Als het document gebruikmaakt van een canonicalisatiemethode die niet in de verzameling staat die wordt vertegenwoordigd door de SafeCanonicalizationMethods eigenschap, wordt de CheckSignature methode geretourneerd false.

Note

Een uiterst defensieve toepassing kan alle waarden verwijderen die niet verwacht worden gebruikt door ondertekenaars uit de SafeCanonicalizationMethods verzameling.

Zijn de referentiewaarden veilig tegen manipulatie?

Ja, de <Reference> waarden zijn veilig tegen manipulatie. .NET verifieert de <SignatureValue> berekening voordat een van de <Reference> waarden en de bijbehorende transformaties worden verwerkt en zal vroeg afbreken om mogelijk schadelijke verwerkingsinstructies te voorkomen.

Kies de elementen die u wilt ondertekenen

U wordt aangeraden de waarde van '' te gebruiken voor het URI kenmerk (of stel de Uri eigenschap in op een lege tekenreeks), indien mogelijk. Dit betekent dat het hele document wordt overwogen voor de samenvattingsberekening, wat betekent dat het hele document wordt beschermd tegen manipulatie.

Het is heel gebruikelijk om waarden te zien URI in de vorm van ankers, zoals #foo, die verwijst naar een element waarvan het id-kenmerk 'foo' is. Helaas is het eenvoudig om hiermee te worden geknoeid, omdat dit alleen de inhoud van het doelelement bevat, niet de context. Misbruik van dit onderscheid staat bekend als XML Signature Wrapping (XSW).

Als uw toepassing van mening is dat opmerkingen semantisch zijn (wat niet gebruikelijk is bij het omgaan met XML), moet u '#xpointer(/)' gebruiken in plaats van '' en '#xpointer(id('foo'))) in plaats van '#foo'. De #xpointer versies worden geïnterpreteerd als inclusief opmerkingen, terwijl de shortname-vormen opmerkingen uitsluiten.

Als u documenten wilt accepteren die slechts gedeeltelijk zijn beveiligd en u ervoor wilt zorgen dat u dezelfde inhoud leest die door de handtekening is beveiligd, gebruikt u de GetIdElement methode.

Beveiligingsoverwegingen over het KeyInfo-element

De gegevens in het optionele <KeyInfo> element (dat wil gezegd de KeyInfo eigenschap) die een sleutel bevat om de handtekening te valideren, mogen niet worden vertrouwd.

Met name wanneer de KeyInfo waarde een openbare RSA-, DSA- of ECDSA-sleutel vertegenwoordigt, is het document mogelijk gemanipuleerd, ondanks de CheckSignature methode die meldt dat de handtekening geldig is. Dit kan gebeuren omdat de entiteit die de manipulatie uitvoert alleen een nieuwe sleutel moet genereren en het geknoeid document opnieuw moet ondertekenen met die nieuwe sleutel. Dus, tenzij uw toepassing controleert of de openbare sleutel een verwachte waarde is, moet het document worden behandeld alsof er met het document is geknoeid. Hiervoor moet uw toepassing de openbare sleutel die in het document is ingesloten, onderzoeken en controleren op basis van een lijst met bekende waarden voor de documentcontext. Als het document bijvoorbeeld kan worden begrepen als afkomstig van een bekende gebruiker, zou u de sleutel vergelijken met een lijst van bekende sleutels die door die gebruiker worden gebruikt.

U kunt de sleutel ook controleren nadat het document is verwerkt met behulp van de CheckSignatureReturningKey methode, in plaats van de CheckSignature methode. Maar voor de optimale beveiliging moet u de sleutel vooraf verifiëren.

U kunt ook overwegen om de geregistreerde openbare sleutels van de gebruiker uit te proberen in plaats van te lezen wat er in het <KeyInfo> element staat.

Beveiligingsoverwegingen over het element X509Data

Het optionele <X509Data> element is een onderdeel van het <KeyInfo> element en bevat een of meer X509-certificaten of identificatoren voor X509-certificaten. De gegevens in het <X509Data> element mogen ook niet inherent worden vertrouwd.

Wanneer u een document verifieert met het ingesloten <X509Data> element, controleert .NET alleen of de gegevens worden omgezet in een X509-certificaat waarvan de openbare sleutel kan worden gebruikt om de documenthandtekening te valideren. In tegenstelling tot het aanroepen van de CheckSignature methode waarvoor de verifySignatureOnly parameter is ingesteld false, wordt er geen intrekkingscontrole uitgevoerd, wordt er geen ketenvertrouwen gecontroleerd en wordt er geen vervaldatum geverifieerd. Zelfs als uw toepassing het certificaat zelf extraheert en doorgeeft aan de CheckSignature methode, waarbij de verifySignatureOnly parameter is ingesteld op false, is dat nog steeds niet voldoende validatie om documenten manipulatie te voorkomen. Het certificaat moet nog steeds worden geverifieerd als geschikt voor het document dat wordt ondertekend.

Het gebruik van een ingesloten handtekeningcertificaat kan nuttige strategieën voor sleutelrotatie bieden, in de <X509Data> sectie of in de documentinhoud. Wanneer u deze methode gebruikt, moet een toepassing het certificaat handmatig extraheren en validatie uitvoeren die vergelijkbaar is met:

  • Het certificaat is rechtstreeks of via een keten uitgegeven door een certificeringsinstantie (CA) waarvan het openbare certificaat is ingesloten in de toepassing.

    Het gebruik van de door het besturingssysteem verstrekte vertrouwenslijst zonder extra controles, zoals een bekende onderwerpnaam, is niet voldoende om manipulatie in SignedXmlte voorkomen.

  • Het certificaat is gecontroleerd en vastgesteld dat het niet is verlopen ten tijde van de ondertekening van het document, of nu voor bijna real-time documentverwerking.

  • Controleer of certificaten met een lange levensduur, die zijn uitgegeven door een CA die intrekking ondersteunt, niet zijn ingetrokken.

  • Het certificaatonderwerp wordt geverifieerd als geschikt voor het huidige document.

Het transformatie-algoritme kiezen

Als u werkt met een specificatie die specifieke waarden (zoals XrML) heeft gedicteerd, moet u de specificatie volgen. Als u een handtekening met enveloppen hebt (bijvoorbeeld bij het ondertekenen van het hele document), moet u deze gebruiken http://www.w3.org/2000/09/xmldsig#enveloped-signature (vertegenwoordigd door de XmlDsigEnvelopedSignatureTransform klas). U kunt ook de impliciete XML-C14N transformatie opgeven, maar dit is niet nodig. Voor een envelop- of losgekoppelde handtekening zijn er geen transformaties vereist. De impliciete XML-C14N transformatie zorgt voor alles.

Met de beveiligingsupdate die is geïntroduceerd door het Microsoft Beveiliging Bulletin MS16-035, .NET beperkt welke transformaties standaard kunnen worden gebruikt bij documentverificatie. Niet-vertrouwde transformaties zorgen ervoor CheckSignature dat ze altijd retourneren false. Met name transformaties waarvoor extra invoer is vereist (opgegeven als onderliggende elementen in de XML) zijn niet toegestaan vanwege hun gevoeligheid voor misbruik door kwaadwillende gebruikers. De W3C adviseert om de XPath- en XSLT-transformaties te vermijden. Dit zijn de twee belangrijkste transformaties die worden beïnvloed door deze beperkingen.

Het probleem met externe verwijzingen

Als een toepassing niet controleert of externe verwijzingen geschikt lijken voor de huidige context, kunnen ze worden misbruikt op manieren die veel beveiligingsproblemen bieden (waaronder Denial of Service, Distributed Reflection Denial of Service, Openbaarmaking van informatie, Handtekening omzeilen en Uitvoering van externe code). Zelfs als een toepassing de externe referentie-URI zou valideren, zou er een probleem blijven dat de resource tweemaal wordt geladen: eenmaal wanneer uw toepassing deze leest en eenmaal wanneer SignedXml deze wordt gelezen. Omdat er geen garantie is dat de stappen voor het lezen en controleren van documenten van de toepassing dezelfde inhoud hebben, biedt de handtekening geen betrouwbaarheid.

Gezien de risico's van externe verwijzingen, SignedXml genereert u een uitzondering wanneer er een externe verwijzing optreedt. Zie .NET toepassingen uitzonderingsfouten tegenkomen voor meer informatie over dit probleem.

Constructors

Name Description
SignedXml()

Initialiseert een nieuw exemplaar van de SignedXml klasse.

SignedXml(XmlDocument)

Initialiseert een nieuw exemplaar van de SignedXml klasse uit het opgegeven XML-document.

SignedXml(XmlElement)

Initialiseert een nieuw exemplaar van de SignedXml klasse van het opgegeven XmlElement object.

Velden

Name Description
m_signature

Vertegenwoordigt het Signature object van het huidige SignedXml object.

m_strSigningKeyName

Vertegenwoordigt de naam van de geïnstalleerde sleutel die moet worden gebruikt voor het ondertekenen van het SignedXml object.

XmlDecryptionTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de xml-modusontsleutelingstransformatie. Dit veld is constant.

XmlDsigBase64TransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de basis 64-transformatie. Dit veld is constant.

XmlDsigC14NTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de Canonical XML-transformatie. Dit veld is constant.

XmlDsigC14NWithCommentsTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de Canonical XML-transformatie, met opmerkingen. Dit veld is constant.

XmlDsigCanonicalizationUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het standaard-canonicalisatie-algoritme voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigCanonicalizationWithCommentsUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het standaard-canonicalisatie-algoritme voor XML-digitale handtekeningen en bevat opmerkingen. Dit veld is constant.

XmlDsigDSAUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het standaardalgoritmen DSA voor digitale XML-handtekeningen. Dit veld is constant.

XmlDsigEnvelopedSignatureTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor transformatie van enveloppen. Dit veld is constant.

XmlDsigExcC14NTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor exclusieve XML-canonicalisatie. Dit veld is constant.

XmlDsigExcC14NWithCommentsTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor exclusieve XML-canonicalisatie, met opmerkingen. Dit veld is constant.

XmlDsigHMACSHA1Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het standaardalgoritmen HMACSHA1 voor digitale XML-handtekeningen. Dit veld is constant.

XmlDsigMinimalCanonicalizationUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het standaard minimale canonicalisatie-algoritme voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigNamespaceUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardnaamruimte voor digitale XML-handtekeningen. Dit veld is constant.

XmlDsigRSASHA1Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardhandtekeningsmethode RSA voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigRSASHA256Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de RSA SHA-256-handtekeningmethodevariatie voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigRSASHA384Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de RSA SHA-384-handtekeningmethodevariatie voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigRSASHA512Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de RSA sha-512-handtekeningmethodevariatie voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigSHA1Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardsamenvatingsmethode SHA1 voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigSHA256Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardsamenvatingsmethode SHA256 voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigSHA384Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardsamenvatingsmethode SHA384 voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigSHA512Url

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de standaardsamenvatingsmethode SHA512 voor XML-digitale handtekeningen. Dit veld is constant.

XmlDsigXPathTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor de XML-padtaal (XPath). Dit veld is constant.

XmlDsigXsltTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor XSLT-transformaties. Dit veld is constant.

XmlLicenseTransformUrl

Vertegenwoordigt de URI (Uniform Resource Identifier) voor het algoritme voor licentietransformatie dat wordt gebruikt voor het normaliseren van XrML-licenties voor handtekeningen.

Eigenschappen

Name Description
EncryptedXml

Hiermee wordt een EncryptedXml object opgehaald of ingesteld waarmee de regels voor XML-versleutelingsverwerking worden gedefinieerd.

KeyInfo

Hiermee wordt het KeyInfo object van het huidige SignedXml object opgehaald of ingesteld.

Resolver

Hiermee stelt u het huidige XmlResolver object in.

SafeCanonicalizationMethods

Hiermee haalt u de namen op van methoden waarvan canonicalisatiealgoritmen expliciet zijn toegestaan.

Signature

Hiermee haalt u het Signature object van het huidige SignedXml object op.

SignatureFormatValidator

Hiermee haalt u een gemachtigde op die wordt aangeroepen om de indeling (niet de cryptografische beveiliging) van een XML-handtekening te valideren.

SignatureLength

Hiermee wordt de lengte van de handtekening voor het huidige SignedXml object opgehaald.

SignatureMethod

Hiermee haalt u de handtekeningmethode van het huidige SignedXml object op.

SignatureValue

Hiermee haalt u de handtekeningwaarde van het huidige SignedXml object op.

SignedInfo

Hiermee haalt u het SignedInfo object van het huidige SignedXml object op.

SigningKey

Hiermee wordt de asymmetrische algoritmesleutel opgehaald of ingesteld die wordt gebruikt voor het ondertekenen van een SignedXml object.

SigningKeyName

Hiermee haalt u de naam op van de geïnstalleerde sleutel die moet worden gebruikt voor het ondertekenen van het SignedXml object.

Methoden

Name Description
AddObject(DataObject)

Hiermee voegt u een DataObject object toe aan de lijst met objecten die moeten worden ondertekend.

AddReference(Reference)

Voegt een Reference object toe aan het object dat een digest-methode, digest-waarde en transformatie beschrijft die moet worden gebruikt voor het SignedXml maken van een digitale XML-handtekening.

CheckSignature()

Bepaalt of de Signature eigenschap verifieert met behulp van de openbare sleutel in de handtekening.

CheckSignature(AsymmetricAlgorithm)

Bepaalt of de Signature eigenschap verifieert voor de opgegeven sleutel.

CheckSignature(KeyedHashAlgorithm)

Bepaalt of de Signature eigenschap verifieert voor het opgegeven MAC-algoritme (Message Authentication Code).

CheckSignature(X509Certificate2, Boolean)

Bepaalt of de Signature eigenschap verifieert voor het opgegeven X509Certificate2 object en, optioneel, of het certificaat geldig is.

CheckSignatureReturningKey(AsymmetricAlgorithm)

Bepaalt of de Signature eigenschap verifieert met behulp van de openbare sleutel in de handtekening.

ComputeSignature()

Berekent een digitale XML-handtekening.

ComputeSignature(KeyedHashAlgorithm)

Hiermee wordt een DIGITALE XML-handtekening berekend met behulp van het opgegeven MAC-algoritme (Message Authentication Code).

Equals(Object)

Bepaalt of het opgegeven object gelijk is aan het huidige object.

(Overgenomen van Object)
GetHashCode()

Fungeert als de standaardhashfunctie.

(Overgenomen van Object)
GetIdElement(XmlDocument, String)

Retourneert het XmlElement object met de opgegeven id van het opgegeven XmlDocument object.

GetPublicKey()

Retourneert de openbare sleutel van een handtekening.

GetType()

Hiermee haalt u de Type huidige instantie op.

(Overgenomen van Object)
GetXml()

Retourneert de XML-weergave van een SignedXml object.

LoadXml(XmlElement)

Hiermee wordt een SignedXml status van een XML-element geladen.

MemberwiseClone()

Hiermee maakt u een ondiepe kopie van de huidige Object.

(Overgenomen van Object)
ToString()

Retourneert een tekenreeks die het huidige object vertegenwoordigt.

(Overgenomen van Object)

Van toepassing op

Zie ook