0

I am trying to digitally sign a XML document using SHA-1 algorithm, but the resulting signed XML has SHA-256 parts in it. I saw this question and tried to adapt it to my function, but it does not work, as it references both SHA-1 and SHA-256 on the resulting XML.

Here is my actual code:

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

    try
    {
        SR = System.IO.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;
                    }
                    //reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1";
                    // Create a SignedXml object.
                    SignedXml signedXml = new SignedXml(doc);
                    // Add the key to the SignedXml document
                    signedXml.SigningKey = x509Cert.PrivateKey;

                    signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
                    // 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 = System.IO.File.CreateText(arquivo))
            {
                sw.Write(conteudoXMLAssinado);
                sw.Close();
            }
        }
    }
    finally
    {
        if (SR != null)
            SR.Close();
    }
}

How to make this function sign just as SHA1?
Here is an example of the output signature:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
   <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
         <Transforms>
            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
         </Transforms>
         <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
         <DigestValue>pp8br9Yd9SdFWQhFdCOJmJlEsKGnlbpovZ6Ssp7VwC4=</DigestValue>
      </Reference>
   </SignedInfo>
   <SignatureValue>ZSWsXhFu6qw5NGy8+hVAA8oW7nUp1vX2Wv+YpnFiC9UWTdRdYlUDjAiah9symfOX2tOEUk69aJjaL/bSZoc5BFFYqQOm2kBVnlbEYQ0lQpvy4sEJodTWiVGaikVldFWUjPkhjwxy9SpreOKBHpEOPkdkyb8SS8k5bE1yA6IbTE3JfyCmeojDSha3lVZzbX8rBN6R2Mwkwg9Eh9dOPjk4+Wu/V5APDQfDa9viQlDAG+gtBTQacMb2aZrNR8fYqm8fSbwhfxgBaMbCqp3A/KqEm9M5Tj8ql/5flRRJ1zmlrwvByfff5+unhdhMzhKcPeoEAkBBJu4RlJVDgf1BNnexNw==</SignatureValue>
   <KeyInfo>
      <X509Data>
         <X509Certificate>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</X509Certificate>
      </X509Data>
   </KeyInfo>
</Signature>

EDIT

Using the suggested code, it returned an error in the line Reference reference = new Reference($"#{list[0].Attributes["id"].Value}");:

NullReferenceException: Object reference not set to an instance of an object.

I'm using the function this way:

SignXmlFile("E:\\nota.xml", "InfDeclaracaoPrestacaoServico", EscolherCertificado());

And here is an example of XML file I'm using with the function:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.issweb.fiorilli.com.br/" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">
   <soapenv:Header />
   <soapenv:Body>
      <ws:gerarNfse>
         <GerarNfseEnvio xmlns="http://www.abrasf.org.br/nfse.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Rps>
               <InfDeclaracaoPrestacaoServico>
                  <Rps>
                     <IdentificacaoRps>
                        <Numero>1</Numero>
                        <Serie>999</Serie>
                        <Tipo>1</Tipo>
                     </IdentificacaoRps>
                     <DataEmissao>2018-11-27</DataEmissao>
                     <Status>1</Status>
                  </Rps>
                  <Competencia>2018-11-27</Competencia>
                  <Servico>
                     <Valores>
                        <ValorServicos>209000</ValorServicos>
                     </Valores>
                     <IssRetido>2</IssRetido>
                     <ItemListaServico>01.05</ItemListaServico>
                     <Discriminacao>Discriminacao teste blablabla</Discriminacao>
                     <CodigoMunicipio>3504800</CodigoMunicipio>
                     <ExigibilidadeISS>1</ExigibilidadeISS>
                  </Servico>
                  <Prestador>
                     <CpfCnpj>
                        <Cnpj>01001001000113</Cnpj>
                     </CpfCnpj>
                     <InscricaoMunicipal>15000</InscricaoMunicipal>
                  </Prestador>
                  <Tomador>
                     <IdentificacaoTomador>
                        <CpfCnpj>
                           <Cpf>35770121025</Cpf>
                        </CpfCnpj>
                     </IdentificacaoTomador>
                     <RazaoSocial>DADOS TOMADOR</RazaoSocial>
                     <Endereco>
                        <Endereco>RUA TOMADOR</Endereco>
                        <Numero>23</Numero>
                        <Complemento>COMPLEMENTO TOMADOR</Complemento>
                        <Bairro>BAIRRO TOMADOR</Bairro>
                        <Uf>MG</Uf>
                        <CodigoPais>1058</CodigoPais>
                        <Cep>37170000</Cep>
                     </Endereco>
                     <Contato>
                        <Telefone>(35) 38511836</Telefone>
                        <Email>mariana@live.com</Email>
                     </Contato>
                  </Tomador>
                  <OptanteSimplesNacional>2</OptanteSimplesNacional>
                  <IncentivoFiscal>2</IncentivoFiscal>
               </InfDeclaracaoPrestacaoServico>
               <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                  <SignedInfo>
                     <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                     <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
                     <Reference URI="">
                        <Transforms>
                           <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                           <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>s8BhRVqeQKRh4H6nlHJEQudBJ+w=</DigestValue>
                     </Reference>
                  </SignedInfo>
                  <SignatureValue>IxrI+sqg6XEg7Dl0utAlJviTKT5fTu1NTErntiSjb61B5q/nP68r4wZ12vqXW5/G92pr+ZUZfLVwnG8vrFx8tsX/eObfpwOxZRfissuuOVQrLmFmHOvLs08VpbkffQpvLIhkpDzLV3pcIPsjgo7UQu+99mB4K+iEZYnfedgmJ8s/6EIcJLoWs9TvJHfpANgbEXSndi0nua1uDr9/FN4oO0jD2lRX+JHp7XJNjcjzS1N/kFG+JSyq0R017Ul0F/qR7dcOsBlFvbXtPcYfT6jiZxHjNf5n0xuK1vBHiwGgFHRFf2oF+2/LwqrCVZxiIMZK3ICdGWfdKkc3YCJ5A4px/g==</SignatureValue>
                  <KeyInfo>
                     <X509Data>
                        <X509Certificate>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</X509Certificate>
                     </X509Data>
                  </KeyInfo>
               </Signature>
            </Rps>
         </GerarNfseEnvio>
         <username>01001001000113</username>
         <password>123456</password>
      </ws:gerarNfse>
   </soapenv:Body>
</soapenv:Envelope>
Pedro Gaspar
  • 777
  • 8
  • 35
Mariana
  • 160
  • 3
  • 15

1 Answers1

1

For the problem you are pointing out, the reason is that you are informing the SignatureMethod as SHA-1:

signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

but you are not informing the reference.DigestMethod as SHA-1, you can see that's just the XML part that is going out as SHA-256, so you have to add this line (actually you did, but it's commented out):

reference.DigestMethod = SignedXml.XmlDsigSHA1Url;

That a look at this answer (on Stack Overflow in Portuguese, but the code part is all in english), it uses SHA-256, but the idea is the same:

E-Social. Assinatura do evento inválida

However, your code is a little bit confusing and you are doing things that don't seem necessary, like opening the XML file as a stream, then loading a XmlDocument using the string read from the stream (why not open the XML file direct as a XmlDocument?), and them you open another XmlDocument again in the end...

But I think that the most important part is that you are expecting that a Signature tag already exists in your input XML, but it should not be that way, you should sign a non-signed XML file, and if a signature already exists in the file, you should remove the old signature before signing it again, since the sign process take the whole document to generate a signature.


Here is a suggestion of how you could do your function for signing a XML file using SHA-1 algorithm:

using System;
using System.Xml;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;

private void SignXmlNodes(
   string filename,
   string mainChildTag,
   string idAttributeTag,
   X509Certificate2 x509Cert)
{
   XmlDocument xmlDoc = new XmlDocument();
   // Format the document to ignore white spaces.
   xmlDoc.PreserveWhitespace = false;
   xmlDoc.Load(filename);

   XmlNodeList mainChildList = xmlDoc.GetElementsByTagName(mainChildTag);
   // Loop through the nodes that need to be signed.
   foreach (XmlNode mainChildNode in mainChildList)
   {
      XmlNode nodeForSigning = mainChildNode.ParentNode;

      // It's necessary to create a namespace manager to use with SelectNode methods,
      // otherwise they won't work, because the node has a specific namespace.
      var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
      nsmgr.AddNamespace("ns", nodeForSigning.NamespaceURI);
      nsmgr.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);

      XmlNode nodeWithTheId = nodeForSigning.SelectSingleNode($"ns:{idAttributeTag}", nsmgr);
      if (nodeWithTheId == null)
      {
         throw new Exception($"The tag with ID attribute '{idAttributeTag}' does not exist in the XML file. (Error code: 4)");
      }
      // Uses null-conditional (?.) and null-coalescing (??) operators to set the reference Uri.
      string refUri = nodeWithTheId.Attributes?["id"]?.Value ?? "";
      if (!string.IsNullOrEmpty(refUri))
      {
         refUri = $"#{refUri}";
      }

      // Remove existing signatures in the node, if there's any.
      foreach (XmlNode node in nodeForSigning.SelectNodes("ds:Signature", nsmgr))
      {
         node.ParentNode.RemoveChild(node);
      }

      SignedXml signedXml = new SignedXml((XmlElement) nodeForSigning);
      // Add the key to the SignedXml document
      signedXml.SigningKey = x509Cert.PrivateKey;
      signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

      // Create a reference with the specified Uri (id of the informed tag).
      Reference reference = new Reference(refUri);
      reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
      reference.AddTransform(new XmlDsigC14NTransform());
      reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
      // Add the reference to the SignedXml object.
      signedXml.AddReference(reference);

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

      // 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 signature element to the XML document.
      //xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
      nodeForSigning.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
   }

   xmlDoc.Save(filename);
}

You can use it like this:

SignXmlNodes("E:\\nota.xml",
             "InfDeclaracaoPrestacaoServico",
             "InfDeclaracaoPrestacaoServico",
             SelectCertificate());
Pedro Gaspar
  • 777
  • 8
  • 35
  • He is signing, but now he is not validating, I will see what may be happening, can it be in the signature? thank you for now. – Mariana Nov 27 '18 at 13:52
  • Probably it has to do with the problems I told you. The XML you are trying to sign already has a signature? What do you really want the function to do? The function will get a XML file, search for a specific tag that has an Id and use it in the reference (or not), sign the doc and save it to a new XML file, that's what you want? – Pedro Gaspar Nov 27 '18 at 14:02
  • @marianac_costa, I've edited my answer to include a suggestion of code for your function, please tell me if it works that way. – Pedro Gaspar Nov 27 '18 at 14:47
  • I need to sign a specific tag and inside another tag, it is not signing, I even generate it, valid in the schema and I subscribe, then when I validate it returns error. I tried this way that you helped me, but it is returning error. – Mariana Nov 27 '18 at 15:36
  • What's the error it's returning? You just want to sign a XML node, not the entire document? Maybe it's better if you put an example of your XML file in your question, with the description of what you expect to do with it, like what nodes you want to sign, if not the whole document. – Pedro Gaspar Nov 27 '18 at 15:41
  • I edited the question showing the errors that are happening, and my xml with the signature the way I was doing. – Mariana Nov 27 '18 at 16:04
  • I can sign, but he still does not validate the signature. I'm checking the reason. Is there any example to generate the xml all in a single line? I'm thinking this might be the reason. Thank you for now. – Mariana Nov 27 '18 at 18:19
  • This error of not being able to validate the signature, can be error at the time of generating the signature? I'm signing an XML file, however every way I sign it is returning the same problem. – Mariana Nov 27 '18 at 19:56
  • What's the error? How are you validating the signed XML? – Pedro Gaspar Nov 27 '18 at 19:59