Sprache

Vorgehensweise: Überprüfen der digitalen Signaturen von XML-Dokumenten

Sie können die Klassen im System.Security.Cryptography.Xml Namespace verwenden, um XML-Daten zu überprüfen, die mit einer digitalen Signatur signiert sind. Mit XML-digitalen Signaturen (XMLDSIG) können Sie überprüfen, ob die Daten nach dem Signieren nicht geändert wurden. Weitere Informationen zum XMLDSIG-Standard finden Sie in der Spezifikation des World Wide Web Consortium (W3C) unter https://www.w3.org/TR/xmldsig-core/.

Hinweis

Der Code in diesem Artikel bezieht sich auf Windows.

Important

Überprüfen Sie immer XML-Signaturen mithilfe einer Überladung CheckSignature , die den Überprüfungsschlüssel oder das Zertifikat als Argument verwendet, und rufen Sie diesen Schlüssel oder Zertifikat von einer Quelle ab, die unabhängig vom signierten Dokument ist (z. B. ein Schlüsselcontainer, wie in diesem Beispiel, Anwendungskonfiguration oder ein an die Anwendung angeheftetes Zertifikat). Verwenden Sie die parameterlose CheckSignature() Überladung nicht, um Dokumente aus einer nicht vertrauenswürdigen Quelle zu authentifizieren: Sie wählt einen Schlüssel aus dem eigenen <KeyInfo> Element des Dokuments aus, der sich unter der Kontrolle der Person befindet, die das Dokument erstellt hat, sodass ein erfolgreiches Ergebnis nicht beweist, dass der Signierer vertrauenswürdig ist. Die vollständige Begründung finden Sie in den Anmerkungen zu SignedXml.

Important

Eine SignedXml Instanz ist für eine einzelne Überprüfung vorgesehen. Rufen Sie CheckSignature nicht mehr als einmal in derselben Instanz auf, und verwenden Sie keine Instanz, die zum Signieren verwendet wurde. In .NET 12 und höher lösen diese Muster InvalidOperationException aus; frühere Versionen von .NET blockieren sie nicht, aber sie können zu falschen Ergebnissen führen. Erstellen Sie für jede Überprüfung eine neue SignedXml.

Das Codebeispiel in diesem Verfahren veranschaulicht, wie eine digitale XML-Signatur in einem <Signature> Element überprüft wird. Das Beispiel ruft einen öffentlichen RSA-Schlüssel aus einem Schlüsselcontainer ab und verwendet dann den Schlüssel, um die Signatur zu überprüfen.

Informationen zum Erstellen einer digitalen Signatur, die mithilfe dieser Technik überprüft werden kann, finden Sie unter How to: SignIEREN von XML-Dokumenten mit digitalen Signaturen.

So überprüfen Sie die digitale Signatur eines XML-Dokuments

  1. Um das Dokument zu überprüfen, müssen Sie denselben asymmetrischen Schlüssel verwenden, der zum Signieren verwendet wurde. Erstellen Sie ein CspParameters Objekt, und geben Sie den Namen des Schlüsselcontainers an, der zum Signieren verwendet wurde.

    CspParameters cspParams = new()
    {
        KeyContainerName = "XML_DSIG_RSA_KEY"
    };
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
  2. Rufen Sie den öffentlichen Schlüssel mithilfe der RSACryptoServiceProvider Klasse ab. Der Schlüssel wird automatisch anhand des Namens aus dem Schlüsselcontainer geladen, wenn Sie das CspParameters Objekt an den Konstruktor der RSACryptoServiceProvider Klasse übergeben.

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Erstellen Sie ein XmlDocument Objekt, indem Sie eine XML-Datei vom Datenträger laden. Das XmlDocument Objekt enthält das zu überprüfende signierte XML-Dokument.

    XmlDocument xmlDoc = new()
    {
        // Load an XML file into the XmlDocument object.
        PreserveWhitespace = true
    };
    xmlDoc.Load("test.xml");
    
    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
  4. Erstellen Sie ein neues SignedXml Objekt, und übergeben Sie das XmlDocument Objekt an das Objekt.

    SignedXml signedXml = new(xmlDoc);
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. Suchen Sie das <signature> Element, und erstellen Sie ein neues XmlNodeList Objekt.

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
    Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
    
  6. Laden Sie den XML-Code des ersten <signature> Elements in das SignedXml Objekt.

    signedXml.LoadXml((XmlElement?)nodeList[0]);
    
    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
  7. Überprüfen Sie die Signatur mithilfe der CheckSignature Methode und des öffentlichen RSA-Schlüssels. Diese Methode gibt einen booleschen Wert zurück, der Erfolg oder Fehler angibt.

    return signedXml.CheckSignature(key);
    
    Return signedXml.CheckSignature(key)
    

Example

In diesem Beispiel wird davon ausgegangen, dass eine Datei "test.xml" namens im selben Verzeichnis wie das kompilierte Programm vorhanden ist. Die "test.xml" Datei muss mit den unter How to: Sign XML Documents with Digital Signatures beschriebenen Techniken signiert werden.

using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

[SupportedOSPlatform("Windows")]
public class VerifyXML
{
    public static void Main(string[] args)
    {
        try
        {
            // Create a new CspParameters object to specify
            // a key container.
            CspParameters cspParams = new()
            {
                KeyContainerName = "XML_DSIG_RSA_KEY"
            };

            // Create a new RSA signing key and save it in the container.
            RSACryptoServiceProvider rsaKey = new(cspParams);

            // Create a new XML document.
            XmlDocument xmlDoc = new()
            {
                // Load an XML file into the XmlDocument object.
                PreserveWhitespace = true
            };
            xmlDoc.Load("test.xml");

            // Verify the signature of the signed XML.
            Console.WriteLine("Verifying signature...");
            bool result = VerifyXml(xmlDoc, rsaKey);

            // 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 (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    // Verify the signature of an XML file against an asymmetric
    // algorithm and return the result.
    public static bool VerifyXml(XmlDocument xmlDoc, RSA key)
    {
        // Check arguments.
        if (xmlDoc == null)
             throw new ArgumentException(null, nameof(xmlDoc));
        if (key == null)
            throw new ArgumentException(null, nameof(key));

        // Create a new SignedXml object and pass it
        // the XML document class.
        SignedXml signedXml = new(xmlDoc);

        // Find the "Signature" node and create a new
        // XmlNodeList object.
        XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");

        // Throw an exception if no signature was found.
        if (nodeList.Count <= 0)
        {
            throw new CryptographicException("Verification failed: No Signature was found in the document.");
        }

        // This example only supports one signature for
        // the entire XML document.  Throw an exception
        // if more than one signature was found.
        if (nodeList.Count >= 2)
        {
            throw new CryptographicException("Verification failed: More that one signature was found for the document.");
        }

        // Load the first <signature> node.
        signedXml.LoadXml((XmlElement?)nodeList[0]);

        // Check the signature and return the result.
        return signedXml.CheckSignature(key);
    }
}
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml

Module VerifyXML
    Sub Main(ByVal args() As String)
        Try
            ' Create a new CspParameters object to specify
            ' a key container.
            Dim cspParams As New CspParameters()
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
            ' Create a new RSA signing key and save it in the container. 
            Dim rsaKey As New RSACryptoServiceProvider(cspParams)
            ' Create a new XML document.
            Dim xmlDoc As New XmlDocument()

            ' Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load("test.xml")
            ' Verify the signature of the signed XML.
            Console.WriteLine("Verifying signature...")
            Dim result As Boolean = VerifyXml(xmlDoc, rsaKey)

            ' 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 Exception
            Console.WriteLine(e.Message)
        End Try
    End Sub

    ' Verify the signature of an XML file against an asymmetric 
    ' algorithm and return the result.
    Function VerifyXml(ByVal xmlDoc As XmlDocument, ByVal key As RSA) As [Boolean]
        ' Check arguments.
        If xmlDoc Is Nothing Then
            Throw New ArgumentException(
                "The XML doc cannot be nothing.", NameOf(xmlDoc))
        End If
        If key Is Nothing Then
            Throw New ArgumentException(
                "The key cannot be nothing.", NameOf(key))
        End If
        ' Create a new SignedXml object and pass it
        ' the XML document class.
        Dim signedXml As New SignedXml(xmlDoc)
        ' Find the "Signature" node and create a new
        ' XmlNodeList object.
        Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
        ' Throw an exception if no signature was found.
        If nodeList.Count <= 0 Then
            Throw New CryptographicException("Verification failed: No Signature was found in the document.")
        End If

        ' This example only supports one signature for
        ' the entire XML document.  Throw an exception 
        ' if more than one signature was found.
        If nodeList.Count >= 2 Then
            Throw New CryptographicException("Verification failed: More that one signature was found for the document.")
        End If

        ' Load the first <signature> node.  
        signedXml.LoadXml(CType(nodeList(0), XmlElement))
        ' Check the signature and return the result.
        Return signedXml.CheckSignature(key)
    End Function
End Module

Code kompilieren

.NET Sicherheit

Speichern oder übertragen Sie niemals den privaten Schlüssel eines asymmetrischen Schlüsselpaars in Nur-Text. Weitere Informationen zu symmetrischen und asymmetrischen kryptografischen Schlüsseln finden Sie unter Generieren von Schlüsseln für Verschlüsselung und Entschlüsselung.

Betten Sie niemals einen privaten Schlüssel direkt in Ihren Quellcode ein. Eingebettete Tasten können mithilfe des Ildasm.exe (IL Disassembler) oder durch Öffnen der Assembly in einem Text-Editor wie Editor problemlos aus einer Assembly gelesen werden.

Siehe auch