Assinando o conteúdo de uma TAG XML com C#

Salve, salve galera,

Atualmente temos visto que muitos órgãos do governo e outras entidades tem adotado o envio de documentos digitais, tais como NF-e, CT-e, SPED, etc, visando uma maior eficiência na apuração e identificação de fraudes. Existe um assunto que é comum em todos esses tramites de dados, o arquivo enviado geralmente (não sempre) é um arquivo XML, e na maioria das vezes é um documento assinado digitalmente com o certificado digital do emissor.

Nesse post, vou mostrar de uma maneira bem simplista e prática como assinar o conteúdo de uma TAG XML e adiciona-la ao respectivo arquivo para fazer o envio do mesmo. Vale lembrar pessoal que a forma que vou mostrar aqui utiliza o certificado A1, e é aceito pelos serviços relacionados a NF-e, se existem variantes desse ou se outros órgãos tem outras restrições é uma questão de analise de caso-a-caso.

Bom mais vamos deixar de bla-bla-bla e vamos por a mão na massa.

A primeira coisa que precisamos fazer é carregar o conteúdo do arquivo XML que iremos assinar. Para conseguir ilustrar melhor vamos partir do principio que esse arquivo a ser assinado é uma NF-e.


XmlDocument docRequest = new XmlDocument();
docRequest.PreserveWhitespace = false;

docRequest.LoadXml(@"C:\MinhaNFe_XML_SemAssinatura.xml");

Agora vamos criar uma instancia da classe SignedXML que é responsável pela tratativa de assinatura de documentos.


SignedXml signedXml;

Feito isso, precisamos identificar qual TAG será assinada, é legal observarmos que, quando falos que vamos assinar uma NF-e por exemplo, nós não assinamos todo o conteúdo do arquivo, e sim uma única TAG, nesse a caso a “infNFe” que contém todos os dados da NF-e. Mas então por que assinar apenas ela e não todo o arquivo ?????? Externo a essa TAG a NF-e possui outras que a SEFAZ entendeu por bem não ser necessário assinar, e também, depois que assinarmos o arquivo iremos adicionar o resultado no arquivo o que mudaria a assinatura se a fizéssemos no arquivo todo. Bom vamos recuperar o conteúdo que queremos assinar.


XmlNodeList ListInfNFe = docRequest.GetElementsByTagName("TAG_A_SER_ASSINADA");

Bom, agora temos o conteúdo que queremos assinar na “agulha” para assinarmos. Agora vamos fazer a mágica. Mas antes disso, precisamos ter uma instancia do certificado digital que iremos utilizar, no nosso exemplo vou buscar o certificado em disco.


X509Certificate2 xCert;
xCert = new X509Certificate2(@"C:\Certificado.pfx", "senha_do_certificado");

Agora vamos ao código.


foreach (XmlElement infNFe in ListInfNFe)

{

     string id = infNFe.Attributes.GetNamedItem("Id").InnerText;
     signedXml = new SignedXml(infNFe);
     signedXml.SigningKey = xCert.PrivateKey;

     Reference reference = new Reference("#" + id);
     reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
     reference.AddTransform(new XmlDsigC14NTransform());
     signedXml.AddReference(reference);

     KeyInfo keyInfo = new KeyInfo();
     keyInfo.AddClause(new KeyInfoX509Data(xCert));

     signedXml.KeyInfo = keyInfo;

     signedXml.ComputeSignature();

     XmlElement xmlSignature = docRequest.CreateElement("Signature", "http://www.w3.org/2000/09/xmldsig#");
     XmlElement xmlSignedInfo = signedXml.SignedInfo.GetXml();
     XmlElement xmlKeyInfo = signedXml.KeyInfo.GetXml();

     XmlElement xmlSignatureValue = docRequest.CreateElement("SignatureValue", xmlSignature.NamespaceURI);
     string signBase64 = Convert.ToBase64String(signedXml.Signature.SignatureValue);
     XmlText text = docRequest.CreateTextNode(signBase64);
     xmlSignatureValue.AppendChild(text);

     xmlSignature.AppendChild(docRequest.ImportNode(xmlSignedInfo, true));
     xmlSignature.AppendChild(xmlSignatureValue);
     xmlSignature.AppendChild(docRequest.ImportNode(xmlKeyInfo, true));

     var evento = docRequest.GetElementsByTagName("TAG_EXTERNA_QUE_CONTERA_A_ASSINATURA");
     evento[0].AppendChild(xmlSignature);

}

Coloquei o código assina na integra para não gerar dúvidas na hora de implementar.

É legal observar que o atributo ID é uma referencia utilizada para assinar, ela é obrigatória para a assinatura mas pode mudar dependendo do arquivo, no caso das NF-e existe um atributo ID, nos outros casos podemos ter mudanças.

Na linha 21, iremos criar uma nova TAG chamada SIGNATURE que ira conter as informações da assinatura.

Na linha 25, criamos a TAG SIGNATUREVALUE que contém efetivamente a assinatura.

Na linha 34, estamos buscando a TAG raiz (no nosso caso) ou qualquer TAG que irá ter dentro dela a assinatura; para poder adicionar essa assinatura dentro do arquivo.

Bom pessoal, a ideia era ser bem prático, uma vez que a demanda por geração de arquivos assinados vem crescendo muito. Qualquer dúvida estou a disposição e mãos na massa galera.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s