Sign XML NFSe

1

I need to sign the following XML:

<?xml version="1.0" encoding="utf-8"?>
<EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/nfse.xsd">
  <LoteRps Id="Id1" versao="Token1">
    <NumeroLote></NumeroLote>
    <CpfCnpj>
      <Cpf></Cpf>
    </CpfCnpj>
    <InscricaoMunicipal></InscricaoMunicipal>
    <QuantidadeRps></QuantidadeRps>
    <ListaRps>
      <Rps>
        <InfDeclaracaoPrestacaoServico Id="Id1">
          <Rps Id="Id1">
            <IdentificacaoRps>
              <Numero></Numero>
              <Serie></Serie>
              <Tipo></Tipo>
            </IdentificacaoRps>
            <DataEmissao></DataEmissao>
            <Status></Status>
            <RpsSubstituido>
              <Numero></Numero>
              <Serie></Serie>
              <Tipo></Tipo>
            </RpsSubstituido>
          </Rps>
          <Competencia></Competencia>
          <Servico>
            <Valores>
              <ValorServicos></ValorServicos>
              <ValorDeducoes></ValorDeducoes>
              <ValorPis></ValorPis>
              <ValorCofins></ValorCofins>
              <ValorInss></ValorInss>
              <ValorIr></ValorIr>
              <ValorCsll></ValorCsll>
              <OutrasRetencoes></OutrasRetencoes>
              <ValorIss></ValorIss>
              <Aliquota></Aliquota>
              <DescontoIncondicionado></DescontoIncondicionado>
              <DescontoCondicionado></DescontoCondicionado>
            </Valores>
            <IssRetido></IssRetido>
            <ResponsavelRetencao></ResponsavelRetencao>
            <ItemListaServico></ItemListaServico>
            <CodigoCnae></CodigoCnae>
            <CodigoTributacaoMunicipio></CodigoTributacaoMunicipio>
            <Discriminacao></Discriminacao>
            <CodigoMunicipio></CodigoMunicipio>
            <CodigoPais></CodigoPais>
            <ExigibilidadeISS></ExigibilidadeISS>
            <MunicipioIncidencia></MunicipioIncidencia>
            <NumeroProcesso></NumeroProcesso>
          </Servico>
          <Prestador>
            <CpfCnpj>
              <Cpf></Cpf>
            </CpfCnpj>
            <InscricaoMunicipal></InscricaoMunicipal>
          </Prestador>
          <Tomador>
            <IdentificacaoTomador>
              <CpfCnpj>
                <Cpf></Cpf>
              </CpfCnpj>
              <InscricaoMunicipal></InscricaoMunicipal>
            </IdentificacaoTomador>
            <RazaoSocial></RazaoSocial>
            <Endereco>
              <Endereco></Endereco>
              <Numero></Numero>
              <Complemento></Complemento>
              <Bairro></Bairro>
              <CodigoMunicipio></CodigoMunicipio>
              <Uf></Uf>
              <CodigoPais></CodigoPais>
              <Cep></Cep>
            </Endereco>
            <Contato>
              <Telefone></Telefone>
              <Email></Email>
            </Contato>
          </Tomador>
          <Intermediario>
            <IdentificacaoIntermediario>
              <CpfCnpj>
                <Cpf></Cpf>
              </CpfCnpj>
              <InscricaoMunicipal></InscricaoMunicipal>
            </IdentificacaoIntermediario>
            <RazaoSocial></RazaoSocial>
          </Intermediario>
          <ConstrucaoCivil>
            <CodigoObra></CodigoObra>
            <Art></Art>
          </ConstrucaoCivil>
          <RegimeEspecialTributacao></RegimeEspecialTributacao>
          <OptanteSimplesNacional></OptanteSimplesNacional>
          <IncentivoFiscal></IncentivoFiscal>
        </InfDeclaracaoPrestacaoServico>
        <Signature Id="ID1" xmlns="http://www.w3.org/2000/09/xmldsig#">
        </Signature>
      </Rps>
    </ListaRps>
  </LoteRps>
</EnviarLoteRpsEnvio>

Is XML right?

The problem is that it does not sign in the signature tag of rps and rather it creates a new tag at the end.

    
asked by anonymous 07.04.2016 / 15:10

1 answer

3

You must specify which tag you want to subscribe to.

private void AssinarXml(string arquivo, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert)
    {
        StreamReader SR = null;

        try
        {                
            SR = File.OpenText(arquivo);
            string xmlString = SR.ReadToEnd();
            SR.Close();
            SR = null;

            // Create a new XML document.
            XmlDocument doc = new XmlDocument();

            // Format the document to ignore white spaces.
            doc.PreserveWhitespace = false;

            // Load the passed XML file using it’s name.
            doc.LoadXml(xmlString);

            if (doc.GetElementsByTagName(tagAssinatura).Count == 0)
            {
                throw new Exception("A tag de assinatura " + tagAssinatura.Trim() + " não existe no XML. (Código do Erro: 5)");
            }
            else if (doc.GetElementsByTagName(tagAtributoId).Count == 0)
            {
                throw new Exception("A tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 4)");
            }                
            else
            {
                XmlDocument XMLDoc;

                XmlNodeList lists = doc.GetElementsByTagName(tagAssinatura);
                foreach (XmlNode nodes in lists)
                {
                    foreach (XmlNode childNodes in nodes.ChildNodes)
                    {
                        if (!childNodes.Name.Equals(tagAtributoId))
                            continue;

                        if (childNodes.NextSibling != null && childNodes.NextSibling.Name.Equals("Signature"))
                            continue;

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

                        XmlElement childElemen = (XmlElement)childNodes;
                        if (childElemen.GetAttributeNode("Id") != null)
                        {
                            reference.Uri = ""; // "#" + childElemen.GetAttributeNode("Id").Value;
                        }
                        else if (childElemen.GetAttributeNode("id") != null)
                        {
                            reference.Uri = "#" + childElemen.GetAttributeNode("id").Value;
                        }

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

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

                        // Add an enveloped transformation to the reference.
                        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
                        reference.AddTransform(env);

                        XmlDsigC14NTransform c14 = new XmlDsigC14NTransform();
                        reference.AddTransform(c14);

                        // Add the reference to the SignedXml object.
                        signedXml.AddReference(reference);

                        // Create a new KeyInfo object
                        KeyInfo keyInfo = new KeyInfo();

                        // Load the certificate into a KeyInfoX509Data object
                        // and add it to the KeyInfo object.
                        keyInfo.AddClause(new KeyInfoX509Data(x509Cert));

                        // Add the KeyInfo object to the SignedXml object.
                        signedXml.KeyInfo = keyInfo;
                        signedXml.ComputeSignature();

                        // Get the XML representation of the signature and save
                        // it to an XmlElement object.
                        XmlElement xmlDigitalSignature = signedXml.GetXml();

                        nodes.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
                    }
                }

                XMLDoc = new XmlDocument();
                XMLDoc.PreserveWhitespace = false;
                XMLDoc = doc;

                string conteudoXMLAssinado = XMLDoc.OuterXml;

                using (StreamWriter sw = File.CreateText(arquivo))
                {
                    sw.Write(conteudoXMLAssinado);
                    sw.Close();
                }
            }
        }           
        finally
        {
            if (SR != null)
                SR.Close();
        }
    }
    
08.04.2016 / 18:48