Ler em inglês

Compartilhar via


Como: assinar documento XML com assinaturas digitais

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

Observação

O código neste artigo se aplica 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 elemento <Signature>. 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. Em seguida, 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 criada usando este procedimento, consulte Como verificar as assinaturas digitais de documentos XML.

Para assinar digitalmente um documento XML

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

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

    RSACryptoServiceProvider rsaKey = new(cspParams);
    
  3. Crie um objeto XmlDocument carregando um arquivo XML do disco. O objeto XmlDocument contém o elemento XML a ser criptografado.

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

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

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

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

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

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

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

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

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

    xmlDoc.Save("test.xml");
    

Exemplo

Este exemplo pressupõe que um arquivo nomeado test.xml exista 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));
    }
}

Compilando o código

Segurança do .NET

Nunca armazene nem transfira a chave privada de um par de chaves assimétricas em texto sem formatação. Para mais informações sobre chaves criptográficas simétricas e assimétricas, confira Como gerar chaves para criptografia e descriptografia.

Nunca insira uma chave privada diretamente no código-fonte. As chaves inseridas podem ser facilmente lidas de um assembly usando Ildasm.exe (Desmontador IL) ou abrindo o assembly em um editor de texto, como o Bloco de Notas.

Confira também