What is causing Malformad Reference Element in my Signature?

Asked

Viewed 835 times

3

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

In a certain situation it doesn’t work, however I never know what situation this is, it is something kind of random.

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

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;

    }

1 answer

1

Good by own experience in digital signature that we perform in the company system, this error occurs because you inform the Id only with letters, inform a signed ID that has the same URI and it confuses.
Example: Id="rps" - so he did not sign and return Malformed Reference Object.

I also went through some cases but well isolated where the Id itself was informed as follows: 'ID or id' and gave this error, but there depends on the system is signing.

At first it is only because of the factor of informing letters only, enter 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 look different, rather simplistic. NOTE: It was an update of . NET from Microsoft that generated this a short time ago. I hope I’ve helped!!

Browser other questions tagged

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