Procedimiento para comprobar las firmas digitales de documentos XMLHow to: Verify the Digital Signatures of XML Documents

Puede usar las clases del espacio de nombres System.Security.Cryptography.Xml para comprobar datos XML firmados con una firma digital.You can use the classes in the System.Security.Cryptography.Xml namespace to verify XML data signed with a digital signature. Las firmas XML digitales (XMLDSIG) permiten comprobar que los datos no se modificaron después de firmarlos.XML digital signatures (XMLDSIG) allow you to verify that data was not altered after it was signed. Para obtener más información sobre el estándar XMLDSIG, consulte la especificación de World Wide Web Consortium (W3C) en https://www.w3.org/TR/xmldsig-core/ .For more information about the XMLDSIG standard, see the World Wide Web Consortium (W3C) specification at https://www.w3.org/TR/xmldsig-core/.

Nota

El código de este artículo se aplica a Windows.The code in this article applies to Windows.

En el ejemplo de código de este procedimiento se muestra cómo comprobar una firma digital XML incluida en un <Signature elemento>.The code example in this procedure demonstrates how to verify an XML digital signature contained in a <Signature> element. En el ejemplo se recupera una clave pública RSA de un contenedor de claves y se usa la clave para comprobar la firma.The example retrieves an RSA public key from a key container and then uses the key to verify the signature.

Para obtener información sobre cómo crear una firma digital que se pueda comprobar mediante esta técnica, consulte Cómo: firmar documentos XML con firmas digitales.For information about how create a digital signature that can be verified using this technique, see How to: Sign XML Documents with Digital Signatures.

Para comprobar la firma digital de un documento XMLTo verify the digital signature of an XML document

  1. Para comprobar el documento, debe usar la misma clave asimétrica que se empleó para la firma.To verify the document, you must use the same asymmetric key that was used for signing. Cree un objeto CspParameters y especifique el nombre del contenedor de claves usado para la firma.Create a CspParameters object and specify the name of the key container that was used for signing.

    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
  2. Recupere la clave pública mediante la clase RSACryptoServiceProvider.Retrieve the public key using the RSACryptoServiceProvider class. La clave se carga automáticamente desde el contenedor de claves por nombre al pasar el objeto CspParameters al constructor de la clase RSACryptoServiceProvider.The key is automatically loaded from the key container by name when you pass the CspParameters object to the constructor of the RSACryptoServiceProvider class.

    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Cree un objeto XmlDocument cargando un archivo XML del disco.Create an XmlDocument object by loading an XML file from disk. El objeto XmlDocument contiene el documento XML firmado que se va a comprobar.The XmlDocument object contains the signed XML document to verify.

    XmlDocument xmlDoc = new XmlDocument();
    
    // Load an XML file into the XmlDocument object.
    xmlDoc.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. Cree un nuevo objeto SignedXml y pásele el objeto XmlDocument.Create a new SignedXml object and pass the XmlDocument object to it.

    SignedXml signedXml = new SignedXml(xmlDoc);
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. Busque el signature elemento <> y cree un nuevo XmlNodeList objeto.Find the <signature> element and create a new XmlNodeList object.

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
    Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("Signature")
    
  6. Cargue el XML del primer <signature elemento> en el SignedXml objeto.Load the XML of the first <signature> element into the SignedXml object.

    signedXml.LoadXml((XmlElement)nodeList[0]);
    
    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
  7. Compruebe la firma con el método CheckSignature y la clave pública RSA.Check the signature using the CheckSignature method and the RSA public key. Este método devuelve un valor booleano que indica éxito o error.This method returns a Boolean value that indicates success or failure.

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

EjemploExample

En este ejemplo se supone que un archivo llamado "test.xml" se encuentra en el mismo directorio que el programa compilado.This example assumes that a file named "test.xml" exists in the same directory as the compiled program. El "test.xml" archivo se debe firmar mediante las técnicas descritas en Cómo: firmar documentos XML con firmas digitales.The "test.xml" file must be signed using the techniques described in How to: Sign XML Documents with Digital Signatures.

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class VerifyXML
{

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

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

            // Create a new XML document.
            XmlDocument xmlDoc = 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...");
            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 Boolean VerifyXml(XmlDocument xmlDoc, RSA key)
    {
        // Check arguments.
        if (xmlDoc == null)
             throw new ArgumentException("xmlDoc");
        if (key == null)
            throw new ArgumentException("key");

        // Create a new SignedXml object and pass it
        // the XML document class.
        SignedXml signedXml = new SignedXml(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("xmlDoc")
        End If
        If key Is Nothing Then
            Throw New ArgumentException("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

Compilar el códigoCompiling the Code

Seguridad de .NET.NET Security

Nunca almacene ni transfiera la clave privada de un par de claves asimétricas en texto sin formato.Never store or transfer the private key of an asymmetric key pair in plaintext. Para obtener más información acerca de las claves criptográficas simétricas y asimétricas, vea generar claves para cifrado y descifrado.For more information about symmetric and asymmetric cryptographic keys, see Generating Keys for Encryption and Decryption.

No inserte nunca una clave privada directamente en el código fuente.Never embed a private key directly into your source code. Las claves incrustadas se pueden leer fácilmente desde un ensamblado mediante el Ildasm.exe (desensamblador de IL) o abriendo el ensamblado en un editor de texto como el Bloc de notas.Embedded keys can be easily read from an assembly using the Ildasm.exe (IL Disassembler) or by opening the assembly in a text editor such as Notepad.

Vea tambiénSee also