SignedXml Klass

Definition

Tillhandahåller en omslutning på ett grundläggande XML-signaturobjekt som underlättar skapandet av XML-signaturer.

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

Exempel

I följande kodexempel visas hur du signerar och verifierar ett helt XML-dokument med en kuverterad signatur.

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

I följande kodexempel visas hur du signerar och verifierar ett enda element i ett XML-dokument med en omslutande signatur.

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

Kommentarer

Klassen SignedXml är .NET-implementeringen av XML-signatursyntaxen och bearbetningsspecifikationen för World Wide Web Consortium (W3C), även kallat XMLDSIG (XML Digital Signature). XMLDSIG är ett standardbaserat, samverkande sätt att signera och verifiera hela eller delar av ett XML-dokument eller andra data som kan adresseras från en URI (Uniform Resource Identifier).

SignedXml Använd klassen när du behöver dela signerade XML-data mellan program eller organisationer på ett standard sätt. Alla data som signeras med den här klassen kan verifieras genom en implementering som överensstämmer med W3C-specifikationen för XMLDSIG.

Med SignedXml klassen kan du skapa följande tre typer av digitala XML-signaturer:

Signaturtyp Description
Kuvertsignatur Signaturen finns i XML-elementet som signeras.
Omslutande signatur Den signerade XML-koden finns i elementet <Signature> .
Intern frånkopplad signatur Signaturen och signerad XML finns i samma dokument, men inget av elementen innehåller det andra.

Det finns också en fjärde typ av signatur som kallas en extern frånkopplad signatur, vilket är när data och signatur finns i separata XML-dokument. Externa frånkopplade signaturer stöds inte av SignedXml klassen.

Struktur för en XML-signatur

XMLDSIG skapar ett <Signature> element som innehåller en digital signatur för ett XML-dokument eller andra data som kan adresseras från en URI. Elementet <Signature> kan också innehålla information om var du hittar en nyckel som verifierar signaturen och vilken kryptografisk algoritm som användes för signering. Den grundläggande strukturen är följande:

<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 viktigaste delarna i den här strukturen är:

  • Elementet <CanonicalizationMethod>

    Anger reglerna för att skriva om elementet Signature från XML/text till byte för signaturverifiering. Standardvärdet i .NET är http://www.w3.org/TR/2001/REC-xml-c14n-20010315, som identifierar en tillförlitlig algoritm. Det här elementet representeras av SignedInfo.CanonicalizationMethod egenskapen .

  • Elementet <SignatureMethod>

    Anger den algoritm som används för generering och validering av signaturer, som tillämpades på elementet <Signature> för att skapa värdet i <SignatureValue>. I föregående exempel identifierar värdet http://www.w3.org/2000/09/xmldsig#rsa-sha1 en RSA PKCS1 SHA-1-signatur. På grund av kollisionsproblem med SHA-1 rekommenderar Microsoft en säkerhetsmodell baserad på SHA-256 eller bättre. Det här elementet representeras av SignatureMethod egenskapen .

  • Elementet <SignatureValue>

    Anger den kryptografiska signaturen för elementet <Signature> . Om signaturen <Signature> inte verifieras manipulerades en del av blocket och dokumentet anses vara ogiltigt. Så länge värdet <CanonicalizationMethod> är tillförlitligt är det här värdet mycket motståndskraftigt mot manipulering. Det här elementet representeras av SignatureValue egenskapen .

  • Attributet URI för elementet <Reference>

    Anger ett dataobjekt med hjälp av en URI-referens. Det här attributet representeras av egenskapen Reference.Uri .

    • Att inte ange URI attributet, det vill säga att ställa in Reference.Uri egenskapen på null, innebär att det mottagande programmet förväntas känna till objektets identitet. I de flesta fall resulterar en null URI i att ett undantag utlöses. Använd inte en null URI, såvida inte programmet samverkar med ett protokoll som kräver det.

    • URI Om attributet anges till en tom sträng anger det att rotelementet i dokumentet signeras, en form av omsluten signatur.

    • Om värdet URI för attributet börjar med #måste värdet matchas mot ett element i det aktuella dokumentet. Det här formuläret kan användas med någon av de signaturtyper som stöds (omsluten signatur, omslutande signatur eller intern frånkopplad signatur).

    • Allt annat anses vara en extern resurs frånkopplad signatur och stöds inte av SignedXml klassen.

  • Elementet <Transforms>

    Innehåller en ordnad lista med <Transform> element som beskriver hur undertecknaren hämtade dataobjektet som sammanfattades. En transformeringsalgoritm liknar canonicalization-metoden, men i stället för att skriva om elementet <Signature> skriver den om innehållet som identifieras av URI elementets <Reference> attribut. Elementet <Transforms> representeras av TransformChain klassen.

    • Varje transformeringsalgoritm definieras som att antingen ta XML (en XPath-noduppsättning) eller byte som indata. Om formatet för aktuella data skiljer sig från kraven för transformeringsindata tillämpas konverteringsregler.

    • Varje transformeringsalgoritm definieras som genererar antingen XML eller byte som utdata.

    • Om utdata från den senaste transformeringsalgoritmen inte definieras i byte (eller om inga transformeringar har angetts) används kanonikaliseringsmetoden som en implicit transformering (även om en annan algoritm angavs i elementet <CanonicalizationMethod> ).

    • http://www.w3.org/2000/09/xmldsig#enveloped-signature Värdet för för transformeringsalgoritmen kodar en regel som tolkas som att ta bort elementet <Signature> från dokumentet. Annars kommer en verifierare av en kuverterad signatur att sammanfatta dokumentet, inklusive signaturen, men undertecknaren skulle ha sammanfattat dokumentet innan signaturen tillämpades, vilket ledde till olika svar.

  • Elementet <DigestMethod>

    Identifierar metoden digest (kryptografisk hash) som ska tillämpas på det transformerade innehåll som identifieras av URI elementets <Reference> attribut. Detta representeras av egenskapen Reference.DigestMethod .

Välja en kanoniskiseringsmetod

Om du inte samverkar med en specifikation som kräver användning av ett annat värde rekommenderar vi att du använder standardmetoden .NET canonicalization, som är algoritmen XML-C14N 1.0, vars värde är http://www.w3.org/TR/2001/REC-xml-c14n-20010315. Algoritmen XML-C14N 1.0 måste stödjas av alla implementeringar av XMLDSIG, särskilt som det är en implicit slutlig transformering att tillämpa.

Det finns versioner av kanoniska algoritmer som stöder bevarande av kommentarer. Kommentarsbevarande kanonikaliseringsmetoder rekommenderas inte eftersom de strider mot principen "signera vad som visas". Kommentarerna i ett <Signature> element ändrar alltså inte bearbetningslogik för hur signaturen utförs, utan bara vad signaturvärdet är. När de tillåter inkluderingen av kommentarer i kombination med en svag signaturalgoritm, ger det en angripare onödig frihet att tvinga fram en hashkollision, vilket gör att ett manipulerat dokument framstår som legitimt. I .NET Framework stöds endast inbyggda kanonikaliserare som standard. Information om hur du stöder ytterligare eller anpassade kanonikaliserare finns i egenskapen SafeCanonicalizationMethods . Om dokumentet använder en kanoniseringsmetod som inte finns i den samling som representeras av SafeCanonicalizationMethods-egenskapen, kommer CheckSignature-metoden att returnera false.

Note

Ett extremt defensivt program kan ta bort alla värden som det inte förväntar sig att undertecknare ska använda från SafeCanonicalizationMethods-samlingen.

Är referensvärdena säkra från manipulering?

Ja, <Reference> värdena är säkra från manipulering. .NET verifierar <SignatureValue> beräkningen innan något av <Reference> värdena och deras associerade transformeringar bearbetas, och avbryts tidigt för att undvika potentiellt skadliga bearbetningsinstruktioner.

Välj de element som ska signeras

Vi rekommenderar att du använder värdet "" för URI attributet (eller anger Uri egenskapen till en tom sträng), om möjligt. Det innebär att hela dokumentet beaktas för den sammanfattade beräkningen, vilket innebär att hela dokumentet skyddas från manipulering.

Det är mycket vanligt att se URI värden i form av fästpunkter som #foo, med hänvisning till ett element vars ID-attribut är "foo". Tyvärr är det enkelt att manipulera detta eftersom det endast innehåller innehållet i målelementet, inte kontexten. Att missbruka denna skillnad kallas för XML Signature Wrapping (XSW).

Om ditt program anser att kommentarer är semantiska (vilket inte är vanligt när du hanterar XML) bör du använda "#xpointer(/)" i stället för "" och "#xpointer(id('foo'))" i stället för "#foo". De #xpointer-versionerna tolkas som inkluderande kommentarer, medan kortnamnsformerna exkluderar kommentarer.

Om du behöver acceptera dokument som endast är delvis skyddade, och du vill se till att du läser samma innehåll som signaturen skyddade, använder du metoden GetIdElement.

Säkerhetsöverväganden om KeyInfo-elementet

Data i det valfria <KeyInfo> elementet (dvs KeyInfo . egenskapen), som innehåller en nyckel för att verifiera signaturen, bör inte vara betrodda.

Särskilt när KeyInfo värdet representerar en offentlig RSA-, DSA- eller ECDSA-nyckel kan dokumentet ha manipulerats, trots CheckSignature att metoden rapporterar att signaturen är giltig. Detta kan inträffa eftersom entiteten som utför manipuleringen bara måste generera en ny nyckel och signera det manipulerade dokumentet igen med den nya nyckeln. Så om inte ditt program verifierar att den offentliga nyckeln är ett förväntat värde ska dokumentet behandlas som om det manipulerades. Detta kräver att ditt program undersöker den offentliga nyckeln som är inbäddad i dokumentet och verifierar den mot en lista med kända värden för dokumentkontexten. Om dokumentet till exempel kan uppfattas som utfärdat av en känd användare kontrollerar du nyckeln mot en lista över kända nycklar som används av användaren.

Du kan också verifiera nyckeln efter att du har bearbetat dokumentet med CheckSignatureReturningKey metoden istället för att använda CheckSignature metoden. Men för optimal säkerhet bör du verifiera nyckeln i förväg.

Alternativt kan du prova användarens registrerade offentliga nycklar i stället för att läsa vad som finns i elementet <KeyInfo> .

Säkerhetsöverväganden om X509Data-elementet

Det valfria <X509Data> elementet är underordnat elementet <KeyInfo> och innehåller ett eller flera X509-certifikat eller identifierare för X509-certifikat. Data i elementet <X509Data> bör inte heller vara betrodda i sig.

När du verifierar ett dokument med det inbäddade <X509Data> elementet verifierar .NET endast att data matchar ett X509-certifikat vars offentliga nyckel kan användas för att verifiera dokumentsignaturen. Till skillnad från att anropa CheckSignature metoden med parametern verifySignatureOnly inställd på falseutförs ingen återkallningskontroll, inget kedjeförtroende kontrolleras och ingen förfallotid verifieras. Även om programmet extraherar själva certifikatet och skickar det till CheckSignature metoden med parametern verifySignatureOnly inställd på false, är det fortfarande inte tillräckligt med validering för att förhindra dokumentmanipulering. Certifikatet måste fortfarande verifieras som lämpligt för det dokument som signeras.

Att använda ett inbäddat signeringscertifikat kan ge användbara nyckelrotationsstrategier, oavsett om det finns i <X509Data>-avsnittet eller dokumentinnehållet. När du använder den här metoden bör ett program extrahera certifikatet manuellt och utföra validering som liknar:

  • Certifikatet utfärdades direkt eller via en kedja av en certifikatutfärdare vars offentliga certifikat är inbäddat i programmet.

    Det räcker inte att använda listan över betrodda operativsystem som tillhandahålls utan ytterligare kontroller, till exempel ett känt ämnesnamn, för att förhindra manipulering i SignedXml.

  • Certifikatet har verifierats att det inte har upphört att gälla vid tidpunkten för dokumentsignering (eller "nu" för dokumentbearbetning i nära realtid).

  • För långvariga certifikat som utfärdats av en certifikatutfärdare som stöder återkallande kontrollerar du att certifikatet inte har återkallats.

  • Certifikatämnet verifieras som lämpligt för det aktuella dokumentet.

Välja transformeringsalgoritmen

Om du samverkar med en specifikation som har dikterat specifika värden (till exempel XrML) måste du följa specifikationen. Om du har en kuverterad signatur (till exempel när du signerar hela dokumentet) måste du använda http://www.w3.org/2000/09/xmldsig#enveloped-signature (representeras av XmlDsigEnvelopedSignatureTransform klassen). Du kan också ange den implicita XML-C14N transformering, men det är inte nödvändigt. För en omslutande eller frånkopplad signatur krävs inga transformeringar. Den implicita XML-C14N-transformen beskriver allt.

Med säkerhetsuppdateringen som introducerades av Microsoft Security Bulletin MS16-035 .NET begränsat vilka transformeringar som kan användas i dokumentverifiering som standard. Ej betrodda transformeringar gör CheckSignature att alltid returnera false. I synnerhet är transformeringar som kräver ytterligare indata (som anges som underordnade element i XML) inte tillåtna på grund av att de är mottagliga för skadliga användares missbruk. W3C rekommenderar att du undviker XPath- och XSLT-transformeringar, som är de två huvudsakliga transformeringar som påverkas av dessa begränsningar.

Problemet med externa referenser

Om ett program inte verifierar att externa referenser verkar lämpliga för den aktuella kontexten kan de missbrukas på ett sätt som ger många säkerhetsrisker (inklusive Denial of Service, Distributed Reflection Denial of Service, Information Disclosure, Signature Bypass och Remote Code Execution). Även om ett program skulle verifiera den externa referens-URI:n skulle det fortfarande finnas ett problem med att resursen läses in två gånger: en gång när programmet läser den och en gång när SignedXml den läses. Eftersom det inte finns någon garanti för att programläsnings- och dokumentkontrollstegen har samma innehåll, ger signaturen inte förtroende.

Med tanke på riskerna med externa referenser utlöser SignedXml ett undantag när en extern referens påträffas. Mer information om det här problemet finns i .NET program stöter på undantagsfel.

Konstruktorer

Name Description
SignedXml()

Initierar en ny instans av SignedXml klassen.

SignedXml(XmlDocument)

Initierar en ny instans av SignedXml klassen från det angivna XML-dokumentet.

SignedXml(XmlElement)

Initierar en ny instans av SignedXml klassen från det angivna XmlElement objektet.

Fält

Name Description
m_signature

Representerar objektet för Signature det aktuella SignedXml objektet.

m_strSigningKeyName

Representerar namnet på den installerade nyckel som ska användas för att signera SignedXml objektet.

XmlDecryptionTransformUrl

Representerar URI (Uniform Resource Identifier) för xml-lägesdekrypteringstransformeringen. Det här fältet är konstant.

XmlDsigBase64TransformUrl

Representerar URI (Uniform Resource Identifier) för bas-64-transformering. Det här fältet är konstant.

XmlDsigC14NTransformUrl

Representerar URI (Uniform Resource Identifier) för den kanoniska XML-omvandlingen. Det här fältet är konstant.

XmlDsigC14NWithCommentsTransformUrl

Representerar URI (Uniform Resource Identifier) för den kanoniska XML-omvandlingen med kommentarer. Det här fältet är konstant.

XmlDsigCanonicalizationUrl

Representerar URI (Uniform Resource Identifier) för standard canonicalization-algoritmen för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigCanonicalizationWithCommentsUrl

Representerar URI (Uniform Resource Identifier) för standardalgoritmen för kanonisering för digitala XML-signaturer och innehåller kommentarer. Det här fältet är konstant.

XmlDsigDSAUrl

Representerar URI (Uniform Resource Identifier) för standardalgoritmen DSA för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigEnvelopedSignatureTransformUrl

Representerar URI (Uniform Resource Identifier) för omsluten signaturtransformering. Det här fältet är konstant.

XmlDsigExcC14NTransformUrl

Representerar URI (Uniform Resource Identifier) för exklusiv XML-kanonisering. Det här fältet är konstant.

XmlDsigExcC14NWithCommentsTransformUrl

Representerar URI (Uniform Resource Identifier) för exklusiv XML-kanonisering med kommentarer. Det här fältet är konstant.

XmlDsigHMACSHA1Url

Representerar URI (Uniform Resource Identifier) för standardalgoritmen HMACSHA1 för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigMinimalCanonicalizationUrl

Representerar URI (Uniform Resource Identifier) för standardalgoritmen för minimal kanonisering för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigNamespaceUrl

Representerar URI (Uniform Resource Identifier) för standardnamnområdet för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigRSASHA1Url

Representerar URI (Uniform Resource Identifier) för standardsignaturmetoden RSA för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigRSASHA256Url

Representerar URI (Uniform Resource Identifier) för SHA-256-signaturmetodvarianten RSA för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigRSASHA384Url

Representerar URI (Uniform Resource Identifier) för SHA-384-signaturmetodvarianten RSA för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigRSASHA512Url

Representerar URI (Uniform Resource Identifier) för SHA-512-signaturmetodvarianten RSA för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigSHA1Url

Representerar URI (Uniform Resource Identifier) för standardmetoden SHA1 för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigSHA256Url

Representerar URI (Uniform Resource Identifier) för standardmetoden SHA256 för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigSHA384Url

Representerar URI (Uniform Resource Identifier) för standardmetoden SHA384 för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigSHA512Url

Representerar URI (Uniform Resource Identifier) för standardmetoden SHA512 för digitala XML-signaturer. Det här fältet är konstant.

XmlDsigXPathTransformUrl

Representerar URI (Uniform Resource Identifier) för XML Path Language (XPath). Det här fältet är konstant.

XmlDsigXsltTransformUrl

Representerar URI (Uniform Resource Identifier) för XSLT-transformeringar. Det här fältet är konstant.

XmlLicenseTransformUrl

Representerar URI (Uniform Resource Identifier) för algoritmen för licenstransformering som används för att normalisera XrML-licenser för signaturer.

Egenskaper

Name Description
EncryptedXml

Hämtar eller anger ett EncryptedXml objekt som definierar reglerna för XML-krypteringsbearbetning.

KeyInfo

Hämtar eller anger objektet för KeyInfo det aktuella SignedXml objektet.

Resolver

Anger det aktuella XmlResolver objektet.

SafeCanonicalizationMethods

Hämtar namnen på metoder vars kanoniska algoritmer uttryckligen tillåts.

Signature

Hämtar objektet för Signature det aktuella SignedXml objektet.

SignatureFormatValidator

Hämtar ett ombud som anropas för att verifiera formatet (inte den kryptografiska säkerheten) för en XML-signatur.

SignatureLength

Hämtar längden på signaturen för det aktuella SignedXml objektet.

SignatureMethod

Hämtar signaturmetoden för det aktuella SignedXml objektet.

SignatureValue

Hämtar signaturvärdet för det aktuella SignedXml objektet.

SignedInfo

Hämtar objektet för SignedInfo det aktuella SignedXml objektet.

SigningKey

Hämtar eller anger den asymmetriska algoritmnyckeln som används för att signera ett SignedXml objekt.

SigningKeyName

Hämtar eller anger namnet på den installerade nyckeln som ska användas för att signera SignedXml objektet.

Metoder

Name Description
AddObject(DataObject)

Lägger till ett DataObject objekt i listan över objekt som ska signeras.

AddReference(Reference)

Lägger till ett Reference objekt i objektet SignedXml som beskriver en sammandragsmetod, sammandragsvärde och transformering som ska användas för att skapa en digital XML-signatur.

CheckSignature()

Avgör om Signature egenskapen verifierar att den offentliga nyckeln används i signaturen.

CheckSignature(AsymmetricAlgorithm)

Avgör om egenskapen Signature verifierar för den angivna nyckeln.

CheckSignature(KeyedHashAlgorithm)

Avgör om egenskapen Signature verifierar för den angivna algoritmen för meddelandeautentiseringskod (MAC).

CheckSignature(X509Certificate2, Boolean)

Avgör om egenskapen Signature verifierar för det angivna X509Certificate2 objektet och eventuellt om certifikatet är giltigt.

CheckSignatureReturningKey(AsymmetricAlgorithm)

Avgör om Signature egenskapen verifierar att den offentliga nyckeln används i signaturen.

ComputeSignature()

Beräknar en digital XML-signatur.

ComputeSignature(KeyedHashAlgorithm)

Beräknar en digital XML-signatur med hjälp av den angivna algoritmen för meddelandeautentiseringskod (MAC).

Equals(Object)

Avgör om det angivna objektet är lika med det aktuella objektet.

(Ärvd från Object)
GetHashCode()

Fungerar som standard-hash-funktion.

(Ärvd från Object)
GetIdElement(XmlDocument, String)

Returnerar objektet XmlElement med det angivna ID:t från det angivna XmlDocument objektet.

GetPublicKey()

Returnerar den offentliga nyckeln för en signatur.

GetType()

Hämtar den aktuella instansen Type .

(Ärvd från Object)
GetXml()

Returnerar XML-representationen av ett SignedXml objekt.

LoadXml(XmlElement)

Läser in ett SignedXml tillstånd från ett XML-element.

MemberwiseClone()

Skapar en ytlig kopia av den aktuella Object.

(Ärvd från Object)
ToString()

Returnerar en sträng som representerar det aktuella objektet.

(Ärvd från Object)

Gäller för

Se även