Compartir a través de


Cómo: Firmar documentos XML con firmas digitales

Actualización: noviembre 2007

Puede utilizar las clases del espacio de nombres System.Security.Cryptography.Xml para firmar un documento XML o parte de un documento XML 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 firmar digitalmente todo un documento XML y adjuntar la firma al documento en un elemento <Signature>. En el ejemplo se crea una clave de firma RSA, se agrega la clave a un contenedor de claves seguro y después se utiliza la clave para firmar digitalmente un documento XML. La clave se podrá recuperar para comprobar la firma digital XML, o bien utilizarse para firmar otro documento XML.

Para obtener información sobre cómo comprobar una firma digital XML creada mediante este procedimiento, vea Cómo: Comprobar las firmas digitales de documentos XML.

Para firmar digitalmente un documento XML

  1. Cree un objeto CspParameters y especifique el nombre del contenedor de claves.

    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
  2. Genere una clave simétrica mediante la clase RSACryptoServiceProvider. La clave se guarda automáticamente en el contenedor de claves cuando pasa el objeto CspParameters al constructor de la clase RSACryptoServiceProvider. Esta clave se utilizará para firmar el documento XML.

    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 elemento XML que se debe cifrar.

    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. Agregue la clave RSA de firma al objeto SignedXml.

    signedXml.SigningKey = Key
    
    signedXml.SigningKey = Key;
    
  6. Cree un objeto Reference que describa qué se debe firmar. Para firmar el documento completo, establezca la propiedad Uri como "".

    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";
    
  7. Agregue un objeto XmlDsigEnvelopedSignatureTransform al objeto Reference. Una transformación permite al comprobador representar los datos XML de idéntico modo que el firmante. Los datos XML se pueden representar de distintas maneras, por lo que este paso es vital para la comprobación.

    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    
  8. Agregue el objeto Reference al objetoSignedXml.

    signedXml.AddReference(reference)
    
    signedXml.AddReference(reference);
    
  9. Llame al método ComputeSignature para calcular la firma.

    signedXml.ComputeSignature()
    
    signedXml.ComputeSignature();
    
  10. Recupere la representación XML de la firma (un elemento <Signature>) y guárdela en un nuevo objeto XmlElement.

    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
  11. Anexe el elemento al objeto XmlDocument.

    Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
    
    Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
    
  12. Guarde el documento.

    xmlDoc.Save("test.xml")
    
    xmlDoc.Save("test.xml");
    

Ejemplo

Imports System
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Xml



Module SignXML


    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")
            ' Sign the XML document. 
            SignXml(xmlDoc, rsaKey)

            Console.WriteLine("XML file signed.")

            ' Save the document.
            xmlDoc.Save("test.xml")


        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

    End Sub



    ' Sign an XML file. 
    ' This document cannot be verified unless the verifying 
    ' code has the key with which it was signed.
    Sub SignXml(ByVal Doc As XmlDocument, ByVal Key As RSA)
        ' 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 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))
    End Sub
End Module
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class SignXML
{

    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");

            // Sign the XML document. 
            SignXml(xmlDoc, rsaKey);

            Console.WriteLine("XML file signed.");

            // Save the document.
            xmlDoc.Save("test.xml");



        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }


    // Sign an XML file. 
    // This document cannot be verified unless the verifying 
    // code has the key with which it was signed.
    public static void SignXml(XmlDocument Doc, RSA Key)
    {
        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

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

    }
}

En este ejemplo se supone que existe un archivo llamado "test.xml" en el mismo directorio que el programa compilado. Puede situar el XML siguiente en un archivo llamado test.xml y utilizarlo con este ejemplo.

<root>
    <creditcard>
        <number>19834209</number>
        <expiry>02/02/2002</expiry>
    </creditcard>
</root>

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: Comprobar las firmas digitales de documentos XML

Referencia

System.Security.Cryptography.Xml

Otros recursos

Cifrado XML y firmas digitales