Compartir a través de


Cómo: Comprobar las firmas digitales de documentos XML

Actualización: noviembre 2007

Puede utilizar las clases del espacio de nombres System.Security.Cryptography.Xml para comprobar datos XML firmados con una firma digital. Las firmas digitales XML (XMLDSIG) permiten comprobar que no se modificaron los datos después de la firma. Para obtener más información sobre el estándar XMLDSIG, vea la especificación de World Wide Web Consortium (W3C) en http://www.w3.org/TR/xmldsig-core/.

En el ejemplo de código de este procedimiento se muestra cómo comprobar una firma digital XML que se encuentra en un elemento <Signature>. En el ejemplo se recupera una clave pública RSA de un contenedor de claves y, a continuación, se utiliza la clave para comprobar la firma.

Para obtener información sobre cómo crear una firma digital que se pueda comprobar mediante esta técnica, vea Cómo: Firmar documentos XML con firmas digitales.

Para comprobar la firma digital de un documento XML

  1. Para comprobar el documento debe utilizar la misma clave asimétrica que se utilizó para la firma. Cree un objeto CspParameters y especifique el nombre del contenedor de claves que se utilizó para la firma.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. Recupere la clave pública mediante la clase RSACryptoServiceProvider. La clave se carga automáticamente del contenedor de claves por nombre cuando se pasa el objeto CspParameters al constructor de la clase RSACryptoServiceProvider.

    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
  3. Cree un objeto XmlDocument; para ello, cargue un archivo XML de disco. El objeto XmlDocument contiene el documento XML firmado para la comprobación.

    Dim xmlDoc As New XmlDocument()
    
    ' Load an XML file into the XmlDocument object.
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load("test.xml")
    
    XmlDocument xmlDoc = 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.

    Dim signedXml As New SignedXml(Doc)
    
    SignedXml signedXml = new SignedXml(Doc);
    
  5. Busque el elemento <signature> y cree un nuevo objeto XmlNodeList.

    Dim nodeList As XmlNodeList = Doc.GetElementsByTagName("Signature")
    
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
    
  6. Cargue el XML del primer elemento <signature> en el objeto SignedXml.

    signedXml.LoadXml(CType(nodeList(0), XmlElement))
    
    signedXml.LoadXml((XmlElement)nodeList[0]);
    
  7. Compruebe la firma mediante el método CheckSignature y la clave pública RSA. Este método devuelve un valor booleano que indica éxito o error.

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

Ejemplo

Imports System
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 Doc As XmlDocument, ByVal Key As RSA) As [Boolean]
        ' Check arguments.
        If Doc Is Nothing Then
            Throw New ArgumentException("Doc")
        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(Doc)
        ' Find the "Signature" node and create a new
        ' XmlNodeList object.
        Dim nodeList As XmlNodeList = Doc.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
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 Doc, RSA Key)
    {
        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

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

        // Find the "Signature" node and create a new
        // XmlNodeList object.
        XmlNodeList nodeList = Doc.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);
    }
}

En este ejemplo se supone que existe un archivo llamado "test.xml" en el mismo directorio que el programa compilado. El archivo "test.xml" se debe firmar mediante las técnicas descritas en Cómo: Firmar documentos XML con firmas digitales.

Compilar el código

Seguridad

Nunca almacene ni transfiera la clave privada de un par de claves asimétricas en texto sin formato. Para obtener más información sobre claves criptográficas simétricas y asimétricas, vea Generar claves para cifrar y descifrar.

No incruste nunca una clave privada directamente en el código fuente. Las claves incrustadas se pueden leer con facilidad de un ensamblado mediante Desensamblador de MSIL (Ildasm.exe) o abriendo el ensamblado con un editor de texto como Bloc de notas.

Vea también

Tareas

Cómo: Firmar documentos XML con firmas digitales

Referencia

System.Security.Cryptography.Xml

Otros recursos

Cifrado XML y firmas digitales