Partilhar via


Como: Assinar documentos XML com assinaturas digitais

Você pode usar as classes no System.Security.Cryptography.Xml namespace para assinar um documento XML ou parte de um documento XML com uma assinatura digital. As assinaturas digitais XML (XMLDSIG) permitem verificar se os dados não foram alterados depois de assinados. Para obter mais informações sobre o padrão XMLDSIG, consulte a recomendação do World Wide Web Consortium (W3C) XML Signature Syntax and Processing.

Nota

O código neste artigo aplica-se ao Windows.

O exemplo de código neste procedimento demonstra como assinar digitalmente um documento XML inteiro e anexar a assinatura ao documento em um <Signature> elemento . O exemplo cria uma chave de assinatura RSA, adiciona a chave a um contêiner de chave segura e usa a chave para assinar digitalmente um documento XML. A chave pode ser recuperada para verificar a assinatura digital XML ou pode ser usada para assinar outro documento XML.

Para obter informações sobre como verificar uma assinatura digital XML que foi criada usando este procedimento, consulte Como verificar as assinaturas digitais de documentos XML.

Para assinar digitalmente um documento XML

  1. Crie um CspParameters objeto e especifique o nome do contêiner de chave.

    CspParameters cspParams = new()
    {
        KeyContainerName = "XML_DSIG_RSA_KEY"
    };
    
    Dim cspParams As New CspParameters With {
        .KeyContainerName = "XML_DSIG_RSA_KEY"
    }
    
  2. Gere uma chave assimétrica usando a RSACryptoServiceProvider classe. A chave é salva automaticamente no contêiner de chave quando você passa o CspParameters objeto para o construtor da RSACryptoServiceProvider classe. Essa chave será usada para assinar o documento XML.

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
    Dim rsaKey As New RSACryptoServiceProvider(cspParams)
    
  3. Crie um XmlDocument objeto carregando um arquivo XML do disco. O XmlDocument objeto contém o elemento XML para criptografar.

    XmlDocument xmlDoc = new()
    {
        // Load an XML file into the XmlDocument object.
        PreserveWhitespace = true
    };
    xmlDoc.Load("test.xml");
    
    ' Load an XML file into the XmlDocument object.
    Dim xmlDoc As New XmlDocument With {
        .PreserveWhitespace = True
    }
    xmlDoc.Load("test.xml")
    
  4. Crie um novo SignedXml objeto e passe o XmlDocument objeto para ele.

    SignedXml signedXml = new(xmlDoc)
    {
    
    Dim signedXml As New SignedXml(xmlDoc)
    
  5. Adicione a chave RSA de assinatura ao SignedXml objeto.

        SigningKey = rsaKey
    };
    
    signedXml.SigningKey = rsaKey
    
  6. Crie um Reference objeto que descreva o que assinar. Para assinar o documento inteiro, defina a Uri propriedade como "".

    // Create a reference to be signed.
    Reference reference = new()
    {
        Uri = ""
    };
    
    ' Create a reference to be signed.
    Dim reference As New Reference()
    reference.Uri = ""
    
  7. Adicione um XmlDsigEnvelopedSignatureTransform objeto ao Reference objeto. Uma transformação permite que o verificador represente os dados XML da mesma maneira que o signatário usou. Os dados XML podem ser representados de diferentes maneiras, portanto, esta etapa é vital para a verificação.

    XmlDsigEnvelopedSignatureTransform env = new();
    reference.AddTransform(env);
    
    Dim env As New XmlDsigEnvelopedSignatureTransform()
    reference.AddTransform(env)
    
  8. Adicione o Reference objeto ao SignedXml objeto.

    signedXml.AddReference(reference);
    
    signedXml.AddReference(reference)
    
  9. Calcule a assinatura chamando o ComputeSignature método.

    signedXml.ComputeSignature();
    
    signedXml.ComputeSignature()
    
  10. Recupere a representação XML da assinatura (um <Signature> elemento) e salve-a em um novo XmlElement objeto.

    XmlElement xmlDigitalSignature = signedXml.GetXml();
    
    Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
    
  11. Acrescente o elemento ao XmlDocument objeto.

    xmlDoc.DocumentElement?.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
    
  12. Salve o documento.

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

Exemplo

Este exemplo pressupõe que um arquivo nomeado test.xml existe no mesmo diretório que o programa compilado. Você pode colocar o XML a seguir em um arquivo chamado test.xml e usá-lo com este exemplo.

<root>  
    <creditcard>  
        <number>19834209</number>  
        <expiry>02/02/2002</expiry>  
    </creditcard>  
</root>  
using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

[SupportedOSPlatform("Windows")]
public class SignXML
{
    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");

            // 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(null, nameof(xmlDoc));
        if (rsaKey == null)
            throw new ArgumentException(null, nameof(rsaKey));

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

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

        // Create a reference to be signed.
        Reference reference = new()
        {
            Uri = ""
        };

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new();
        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 With {
                .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.
            ' Load an XML file into the XmlDocument object.
            Dim xmlDoc As New XmlDocument With {
                .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(
                "The XML doc cannot be nothing.", NameOf(xmlDoc))
        End If
        If rsaKey Is Nothing Then
            Throw New ArgumentException(
                "The RSA key cannot be nothing.", 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

Compilando o código

Segurança do .NET

Nunca armazene ou transfira a chave privada de um par de chaves assimétricas em texto simples. Para obter mais informações sobre chaves criptográficas simétricas e assimétricas, consulte Gerando chaves para criptografia e descriptografia.

Nunca incorpore uma chave privada diretamente no seu código-fonte. As teclas incorporadas podem ser facilmente lidas a partir de uma montagem usando o Ildasm.exe (IL Disassembler) ou abrindo a montagem em um editor de texto, como o Bloco de Notas.

Consulte também