Hello!. I am trying to sign an xml with a key (.pfx) and when I sent it to who should receive it I get in response "Incorrect reference digest value". I am working with C# and I need your help to solve my problem. Here is my code, which I got (in part) from MSDN

private static void SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert)
    {
        RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)uidCert.PrivateKey;

        // Create a SignedXml object .
        SignedXml signedXml = new SignedXml(xmlDoc);

        signedXml.SigningKey = rsaKey;

        Reference reference = new Reference();
        reference.Uri = "";

        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);
        signedXml.AddReference(reference);

        KeyInfo keyInfo = new KeyInfo();

        KeyInfoX509Data clause = new KeyInfoX509Data();
        clause.AddSubjectName(uidCert.Subject);
        clause.AddCertificate(uidCert);
        keyInfo.AddClause(clause);
        signedXml.KeyInfo = keyInfo;

        // Compute signature.
        signedXml.ComputeSignature();

        XmlElement xmlDigitalSignature = signedXml.GetXml();
        xmlDigitalSignature.Prefix = "ds";
        signedXml.ComputeSignature();

        MessageBox.Show(signedXml.GetXml().InnerXml);

        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        //check signature
        XmlNodeList nodeList = xmlDoc.GetElementsByTagName("ds:Signature");
        if (nodeList.Count <= 0)
        {
            MessageBox.Show("Verification failed: No Signature was found in the document.");
        }
        else if (nodeList.Count >= 2)
        {
            MessageBox.Show("Verification failed: More that one signature was found for the document.");
        }
        else
        {
            signedXml.LoadXml((XmlElement)nodeList[0]);
            if (signedXml.CheckSignature())
            {
                MessageBox.Show("signature ok");
            }
            else
            {
                MessageBox.Show("signature failed");
            }
        }
    } 

By the way, I could not donate because my debit card was rejected...???

You are computing signedXml.ComputeSignature(); on line 26 and on line 30. Is that intentional?

I take it you mean these tutorials on verifying and signing. I only see it being used once there.

From the documentation:

The ComputeSignature method creates an XML digital signature and constructs many of the XML elements needed. You must set the data to be signed and the SigningKey property before calling this method.

So doing it twice might mess things up.

Disclaimer: I'm not an expert in C#

Edit: I just found your StackOverflow question and there I see you mention SoapUI. A "common" issue in Java with signed xml not verifying is that you sign the entire SOAP envelope instead of just the body. But I can't tell if that's what you're trying to do here.

First of all, thanks for your answer.
Yes, I compute twice the signature because I add the namespace "ds", that was the idea; I supposed it wouldn't cause any damage....
I followed your suggestion and tried to send just the xml (without envelop). Bad luck.

Yes, I am testing my signed xml via SOAPUI, and I received "Incorrect reference digest value". I tried testing my doc in a website I found htps://www.aleksey.com/cgi-bin/xmldsigverify (I erase one letter t from https....) and I got this

func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=250:obj=sha1:subj=unknown:error=12:invalid data:data and digest do not match RESULT: Signature is INVALID

Therefore, I am doing something wrong. Can you help me?

I followed your suggestion and tried to send just the xml (without envelop). Bad luck.

No no, my point was that you might be signing the envelope and only verifying the body, or signing the envelope which later gets expanded and then trying to verify it.

I can't reproduce your code myself (mostly because I haven't downloaded Rider yet) but these are the things I would try:

  • Remove one of the signedXml.ComputeSignature(); (the first one if you worry about the ds addition).
  • Remove the part you added with the X509Certificate2 to see if it works without.
  • Revert the code back to the original tutorial to see if that one works for you (i.e. without the ds addition, without the certificate). Perhaps check in a new project, copy the tutorial and if that works slowly start adding your changes until it breaks.
  • Remove the signing completely and ensure you can actually send the xml across normally.

Other things that might be happening:

  • a newline \n or \r\n is/are being added to the xml along the way (thus failing the signature)
  • whitespaces might be added along the way
  • the character encoding of the xml has changed along the way
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.