'Malformed Reference Element' when adding a reference based on an Id attribute with SignedXml class

21,168

Solution 1

The approach we used was to subclass System.Security.Cryptography.Xml.SignedXml class...

public class SignedXmlWithId : SignedXml
{
    public SignedXmlWithId(XmlDocument xml) : base(xml)
    {
    }

    public SignedXmlWithId(XmlElement xmlElement) 
        : base(xmlElement)
    {       
    }

    public override XmlElement GetIdElement(XmlDocument doc, string id)
    {
        // check to see if it's a standard ID reference
        XmlElement idElem = base.GetIdElement(doc, id);

        if (idElem == null)
        {
            XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
            nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement;
        }

        return idElem;
    }
}

Solution 2

var reference = new Reference(""); // This will sign the entire document

Solution 3

It should be noted that you will need to use SignedXmlWithId object instead of SignedXml object in order to be able to use the overridden GetIdElement() method. Once I did that, I was able to sign an XmlElement and get around the Malformed Reference Element error.

See my post about this topic here.

Share:
21,168

Related videos on Youtube

Dog Ears
Author by

Dog Ears

Updated on March 03, 2020

Comments

  • Dog Ears
    Dog Ears about 4 years

    Unable to sign element by Id attribute when there's a namespace prefix:

    void Main()
    {
        var doc = new XmlDocument();
        doc.LoadXml("<root xmlns:u=\"myuri\"><test u:Id=\"_0\">Zebra</test></root>");
    
        SignedXml signedXml = new SignedXml(doc);
        signedXml.SigningKey = new RSACryptoServiceProvider();
    
        Reference reference = new Reference("#_0");
        signedXml.AddReference(reference);
    
        signedXml.ComputeSignature();
    }
    

    ComputeSignature() will fail here with 'Malformed Reference Element' how should this be done?

  • Dog Ears
    Dog Ears about 13 years
    But I need to supply the id of the element to sign..the actual xml is a soap envelope and using Ids seems to be the way that it's done.
  • Richard Schneider
    Richard Schneider about 13 years
    ok, the xml has atttibute "u:Id", if you change it to "<test Id='0'>...", then ComputeSignature should work. If you can not change the input then you will have use a "#xpointer" reference.
  • Bon
    Bon over 8 years
    You are my hero for today. Thank you.
  • Jan Friedrich
    Jan Friedrich about 8 years
    I had the same error, but the problem was that the value for SecurePart\Id started with number (only characters are allowed).
  • Dog Ears
    Dog Ears about 8 years
    @JanFriedrich you should post a working answer, I'll willing accept that if correct.
  • Michael Ritchson
    Michael Ritchson over 4 years
    @JanFriedrich, that was my issue as well. I was working with an ID for a SAML request. Had to conform to the XML ID convention. See w3.org/TR/xml-id which is an NCNAME w3.org/TR/xml-names11/#NT-NCName, which the starting character is restricted. I used a GUID with no braces, just prepended it with an _ for the ID.