c# – What is causing Malformad Reference Element in my Signature?

Question:

I'm trying to sign an XML passing the reference tag, id, XML and certificate.

In a certain situation it doesn't work, but I never know what that situation is, it's kind of random.

And now, even though I change the reference.uri to put an underline or not, it's not going through the ComputeSignature() method.

can you help me?

 public string Assinar(string XMLString, string RefUri, X509Certificate2 _X509Cert, object id, bool assinarTagSignature = true)
    {
        string xmlResultado = string.Empty;
        try
        {
            string x;
            x = _X509Cert.GetKeyAlgorithm().ToString();
            //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.
            try
            {
                try
                {
                    doc.LoadXml(XMLString);
                }
                catch (Exception ex)
                {
                    sResultado = XMLString;
                    throw new Exception("erro ao ler");
                }

                //Verifica se a tag a ser assinada existe é única
                int qtdeRefUri = doc.GetElementsByTagName(RefUri).Count;
                if (qtdeRefUri == 0)
                {
                    //a URI indicada não existe
                    iResultado = 4;
                    sResultado = "A tag de assinatura " + RefUri.Trim() + " inexiste";

                }
                //Exsiste mais de uma tag a ser assinada
                else
                {
                    if (qtdeRefUri > 1)
                    {
                        //Existe mais de uma URI indicada
                        iResultado = 5;
                        sResultado = "A tag de assinatura " + RefUri.Trim() + " não é unica";
                    }
                    else
                    {
                        try
                        {
                            //Create a SignedXml object.
                            SignedXml signedXml = new SignedXml(doc);


                            //Add the key to the SignedXml document 
                            signedXml.SigningKey = _X509Cert.PrivateKey;
                            //Create a reference to be signed
                            Reference reference = new Reference();
                            //pega o uri que deve ser assinada
                            XmlAttributeCollection tagUri = doc.GetElementsByTagName(RefUri).Item(0).Attributes;

                            if (id.ToString() != "0")
                                foreach (XmlAttribute _atributo in tagUri)
                                {
                                    if (_atributo.Name == "Id")
                                    {
                                        reference.Uri = "#" + _atributo.InnerText;
                                        //reference.Uri = _atributo.InnerText;
                                    }
                                }
                            else
                                reference.Uri = "";

                            /*
                            foreach (XmlAttribute _atributo in tagUri)
                            {

                                if (_atributo.Name == "Id")
                                {
                                    reference.Uri = "#" + _atributo.InnerText;
                                }
                            }
                            */

                            //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();


                            if (assinarTagSignature)
                                xmlDigitalSignature.SetAttribute("Id", "Ass_" + id.ToString());

                            //Append the element to the XML document.
                            doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
                            XmlDocument XMLDoc = new XmlDocument();
                            XMLDoc.PreserveWhitespace = false;
                            XMLDoc = doc;

                            xmlResultado = XMLDoc.InnerXml;

                        }

                        catch (Exception caught)
                        {

                            iResultado = 7;

                            sResultado = "Erro: Ao assinar o documento - " + caught.Message;

                        }

                    }

                }

            }

            catch (Exception caught)
            {

                iResultado = 3;

                sResultado = "XML mal formado - " + caught.Message + " " + XMLString;

            }

        }

        catch (Exception caught)
        {

            iResultado = 1;

            sResultado = sResultado = "Problemas na seleção do certificado digital: " + caught.Message;

        }

        sResultado = "Arquivo Assinado Com Sucesso";

        return xmlResultado;

    }

Answer:

Well from experience in digital signature that we performed in the company's system, this error occurs because you enter the Id with letters only, enter a signed ID that will have the same URI and it will get confused.
Example: Id="rps" – this way it will not sign and return the Malformed Reference Object.

I also went through some cases but very isolated where the Id was informed in the following way: 'ID or id' and I gave this error, but it depends on the system you are signing.

At first it's just because of the factor of informing letters only, inform letters and numbers, and if there is more than one field to be signed, you put a different ID, put a random hash generator to be different, it simplifies a lot. NOTE: It was a Microsoft .NET update that generated this a short time ago. Hope this helps!!

Scroll to Top