Procedimiento para firmar documentos XML con firmas digitalesHow to: Sign XML Documents with Digital Signatures

Puede usar 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.You can use the classes in the System.Security.Cryptography.Xml namespace to sign an XML document or part of an XML document 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 recomendación de World Wide Web Consortium (W3C) XML Signature Syntax and Processing.For more information about the XMLDSIG standard, see the World Wide Web Consortium (W3C) recommendation XML Signature Syntax and Processing.

El ejemplo de código en este procedimiento muestra cómo firmar un documento XML completo y adjuntar la firma al documento en un <Signature> elemento.The code example in this procedure demonstrates how to digitally sign an entire XML document and attach the signature to the document in a <Signature> element. En el ejemplo se crea una clave de firma RSA, se agrega la clave a un contenedor de claves seguro y, a continuación, se usa la clave para firmar digitalmente un documento XML.The example creates an RSA signing key, adds the key to a secure key container, and then uses the key to digitally sign an XML document. La clave se puede recuperar para comprobar la firma digital XML, o bien se puede usar para firmar otro documento XML.The key can then be retrieved to verify the XML digital signature, or can be used to sign another XML document.

Para obtener información acerca de cómo comprobar una firma digital XML creada mediante este procedimiento, vea Cómo: Comprobar las firmas digitales de documentos XML.For information about how to verify an XML digital signature that was created using this procedure, see How to: Verify the Digital Signatures of XML Documents.

Para firmar digitalmente un documento XMLTo digitally sign an XML document

  1. Cree un objeto CspParameters y especifique el nombre del contenedor de claves.Create a CspParameters object and specify the name of the key container.

    CspParameters cspParams = new CspParameters();
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
    Dim cspParams As New CspParameters()
    cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"
    
  2. Genere una clave asimétrica mediante la clase RSACryptoServiceProvider.Generate an asymmetric key using the RSACryptoServiceProvider class. La clave se guarda automáticamente en el contenedor de claves al pasar el objeto CspParameters al constructor de la clase RSACryptoServiceProvider.The key is automatically saved to the key container when you pass the CspParameters object to the constructor of the RSACryptoServiceProvider class. Esta clave se usará para firmar el documento XML.This key will be used to sign the XML document.

    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 elemento XML que se va a cifrar.The XmlDocument object contains the XML element to encrypt.

    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. Agregue la clave RSA de firma al objeto SignedXml.Add the signing RSA key to the SignedXml object.

    signedXml.SigningKey = rsaKey;
    
    signedXml.SigningKey = rsaKey
    
  6. Cree un objeto Reference que describa qué se va a firmar.Create a Reference object that describes what to sign. Para firmar el documento completo, establezca la propiedad Uri en "".To sign the entire document, set the Uri property to "".

    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";
    
    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
  7. Agregue un objeto XmlDsigEnvelopedSignatureTransform al objeto Reference.Add an XmlDsigEnvelopedSignatureTransform object to the Reference object. Una transformación permite al comprobador representar los datos XML de un modo idéntico al que usó el firmante.A transformation allows the verifier to represent the XML data in the identical manner that the signer used. Los datos XML se pueden representar de maneras diferentes, por lo que este paso es vital para la comprobación.XML data can be represented in different ways, so this step is vital to verification.

    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);
    
    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
  8. Agregue el objeto Reference al objeto SignedXml.Add the Reference object to the SignedXml object.

    signedXml.AddReference(reference);
    
    signedXml.AddReference(reference)
    
  9. Calcule la firma llamando al método ComputeSignature.Compute the signature by calling the ComputeSignature method.

    signedXml.ComputeSignature();
    
    signedXml.ComputeSignature()
    
  10. Recuperar la representación XML de la firma (un <Signature> elemento) y guárdelo en un nuevo XmlElement objeto.Retrieve the XML representation of the signature (a <Signature> element) and save it to a new XmlElement object.

    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
  11. Anexe el elemento al objeto XmlDocument.Append the element to the XmlDocument object.

    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    
  12. Guarde el documento.Save the document.

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

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. Puede colocar el siguiente código XML en un archivo llamado test.xml y usarlo con este ejemplo.You can place the following XML into a file called test.xml and use it with this example.

<root>  
    <creditcard>  
        <number>19834209</number>  
        <expiry>02/02/2002</expiry>  
    </creditcard>  
</root>  
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 xmlDoc, RSA rsaKey)
    {
        // Check arguments.
        if (xmlDoc == null)
            throw new ArgumentException(nameof(xmlDoc));
        if (rsaKey == null)
            throw new ArgumentException(nameof(rsaKey));

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = rsaKey;

        // 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.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    }
}
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 xmlDoc As XmlDocument, ByVal rsaKey As RSA)
        ' Check arguments.
        If xmlDoc Is Nothing Then
            Throw New ArgumentException(NameOf(xmlDoc))
        End If
        If rsaKey Is Nothing Then
            Throw New ArgumentException(NameOf(rsaKey))
        End If
        ' Create a SignedXml object.
        Dim signedXml As New SignedXml(xmlDoc)
        ' Add the key to the SignedXml document.
        signedXml.SigningKey = rsaKey
        ' 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.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    End Sub
End Module

Compilar el códigoCompiling the Code

Seguridad de .NET Framework.NET Framework 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 insertadas se pueden leer fácilmente desde un ensamblado mediante la Ildasm.exe (Desensamblador de IL) o abriendo el ensamblado en un editor de texto como 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