What is causing Malformed Reference Element in my Signature?

1

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

In a certain situation it does not work, but I never know what the situation is, it's a bit random.

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

Could 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;

    }
    
asked by anonymous 17.03.2017 / 16:49

1 answer

0

Good for our own digital signature experience, this error is due to the fact that you only enter the ID with letters, 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 a few but well-isolated cases where Id itself was reported as follows: 'id or id' and gave this error, but then it depends on the system it is signing.

At first it's just because of the factor of informing letters only, inform letter 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, simplistic enough. NOTE: It was a Microsoft .NET update that spawned this recently. Hope this helps!!

    
16.06.2017 / 15:00