C# XML digital signature, poorly formed Reference element

Asked

Viewed 1,248 times

3

I have a code c# that generates a xml with digital signature, but when calling the function signedXml.ComputeSignature() it shows the following error:

Badly formed Reference element.

However, I researched about this error and most websites or forums cite the removal of the update KB3136000, only that in the windows 10 that I’m using doesn’t have this update installed.

What can it be?

Follow the code below highlighting the error line:

public static void AssinaDocumento(X509Certificate2 certificadoDigital, string Uri, string xmlOrigem)
{
    int countTagsUri;
    XmlDocument xmlDocument = new XmlDocument();
    XmlDocument xmlDocument2 = new XmlDocument();
    xmlDocument.PreserveWhitespace = false;
    XmlNodeList xmlNodeList;
    Reference reference = new Reference();

    xmlDocument.Load(xmlOrigem);

    xmlDocument2 = xmlDocument;

    XmlDocument xmlAssinado = xmlDocument;
    SignedXml signedXml = new SignedXml(xmlDocument);
    signedXml.SigningKey = certificadoDigital.PrivateKey;

    countTagsUri = xmlDocument.GetElementsByTagName(Uri).Count;
    if (countTagsUri == 0)
    {
        throw new Exception("Uri " + Uri + " não encontrada no XML");
    }

    xmlNodeList = xmlDocument.GetElementsByTagName(Uri);

    foreach (XmlNode xmlnl in xmlNodeList)
    {
        XmlAttributeCollection attributeCollection = xmlnl.FirstChild.Attributes;
        reference.Uri = "#" + attributeCollection["id"].InnerText;

        string res = xmlnl.OuterXml;

        XmlDsigEnvelopedSignatureTransform envelope = new XmlDsigEnvelopedSignatureTransform();
        XmlDsigC14NTransform c14NTransform = new XmlDsigC14NTransform();
        KeyInfo keyInfo = new KeyInfo();

        reference.AddTransform(envelope);
        reference.AddTransform(c14NTransform);

        signedXml.AddReference(reference);

        keyInfo.AddClause(new KeyInfoX509Data(certificadoDigital));

        signedXml.KeyInfo = keyInfo;

        signedXml.ComputeSignature(); // O erro Ocorre aqui

        XmlElement xmlDigitalSignature = signedXml.GetXml();

        XmlNode xmlNode = xmlDocument.ImportNode(xmlDigitalSignature, true);


        xmlDocument.FirstChild.NextSibling.LastChild.InsertAfter(xmlNode, xmlnl.LastChild);


        xmlDocument.PreserveWhitespace = true;
        xmlDocument.Save(@"C:\Users\ter0038\Desktop\assinado.xml");
    }
}
  • Good morning. No one has a solution for this yet?

2 answers

0

Hello, With the deactivation of Win7 and everyone migrates to Win10 then you should START the Id with letter and not with number. (This happens a lot with people who implement Nfse for prefectures). I say this because some Velopers indicate the Removal of some Win7 updates Example:

(ERRADO)       
        <EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd">
            <LoteRps id="002">
        </EnviarLoteRpsEnvio>

(CERTO)    
    <EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd">
        <LoteRps id="A002">, onde A pode ser qualquer letra não especial 
    </EnviarLoteRpsEnvio>

0

Try it with this code:

        private XmlDocument 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;
                            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;

                return XMLDoc;
                //string conteudoXMLAssinado = XMLDoc.OuterXml;

                //using (StreamWriter sw = File.CreateText(arquivo))
                //{
                //    sw.Write(conteudoXMLAssinado);
                //    sw.Close();
                //}
            }
        }
        finally
        {
            if (SR != null)
                SR.Close();
        }
    }
  • Thanks for the help. The same error persists. " Badly formed Reference Element."

Browser other questions tagged

You are not signed in. Login or sign up in order to post.