Reference element with incorrect format

carlosp

Member
Joined
Aug 9, 2022
Messages
5
Programming Experience
5-10
I want to sign an xml, so it's giving an error: Reference element with incorrect format XMLDSig standard, must also comply with the XAdES-BES standard
i send one exemple
this is my cod
C#:
static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
{
    const string signedPropsIdSuffix = "-signedprops";
    var signedXml = new SignedXml(doc)
    {
        SigningKey = cert.GetRSAPrivateKey()
    };
    signedXml.SignedInfo.CanonicalizationMethod = "Exclusive XML Canonicalization Version 1.0";
    signedXml.SignedInfo.SignatureMethod = "xmldsig-more namespace";

    var idKeyInfo = "xmldsig-" + Guid.NewGuid();
    var idKeyInfoProps = "#xmldsig-" + Guid.NewGuid() + signedPropsIdSuffix;
    var idKeyInfoProps1 = "#xmldsig-" + Guid.NewGuid() + "-keyinfo";

    #region keyinfo

    var keyInfo = new KeyInfo();
    var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
    keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
    keyInfo.AddClause(keydata);
    keyInfo.Id = idKeyInfo;
    signedXml.KeyInfo = keyInfo;

    #endregion keyinfo

    #region References

    //var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "Exclusive XML Canonicalization Version 1.0" };
    var transform = new XmlDsigExcC14NTransform();
    var references = new List<Reference>();
    // first reference
    var keyInfoReference = new Reference();
    keyInfoReference.Uri = "#" + keyInfo.Id;
    keyInfoReference.DigestMethod = "XML Encryption Syntax and Processing";
    keyInfoReference.AddTransform(transform);
    references.Add(keyInfoReference);

    //second reference
    var signaturePropertiesReference = new Reference();
    signaturePropertiesReference.Type =
      "Assigned ETSI XML URIs";
    signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
    signaturePropertiesReference.DigestMethod = "XML Encryption Syntax and Processing";
    signaturePropertiesReference.AddTransform(transform);
    references.Add(signaturePropertiesReference);

    //third reference
    var documentReference = new Reference();
    documentReference.DigestMethod = "XML Encryption Syntax and Processing";
    // The code in the question didn't assign Uri, and since no transform did an inherent
    // node resolution, signing failed.
    documentReference.Uri = "";
    documentReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
    documentReference.AddTransform(transform);
    references.Add(documentReference);

    foreach (Reference reference in references)
    {
        signedXml.AddReference(reference);
    }

    #endregion

    #region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime

    var URI = "Assigned ETSI XML URIs";
    XmlElement qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);

    XmlElement signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
    signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);

    XmlElement SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
    XmlElement timestamp = doc.CreateElement("xades", "SigningTime", URI);
    timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");    // primero de la lista

    signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
    SignedSignatureProperties.AppendChild(timestamp);
    qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);

    var qualifyingPropertiesObject = new System.Security.Cryptography.Xml.DataObject
    {
        Data = qualifyingPropertiesRoot.SelectNodes("."),
        //Id = idKeyInfoProps
    };
    signedXml.AddObject(qualifyingPropertiesObject);
    #endregion

    SignedXml tmp = new SignedXml(doc)
    {
        SigningKey = signedXml.SigningKey,
        KeyInfo = signedXml.KeyInfo,
    };

    foreach (System.Security.Cryptography.Xml.DataObject obj in
    signedXml.Signature.ObjectList)
    {
        tmp.AddObject(obj);
    }

    tmp.AddReference(new Reference(""));
    tmp.ComputeSignature();
    XmlElement elem = tmp.GetXml();
    doc.DocumentElement.AppendChild(elem);
    Console.WriteLine("Stage 1 signed");
    signedXml.ComputeSignature();
    doc.DocumentElement.RemoveChild(elem);
    doc.DocumentElement.AppendChild(signedXml.GetXml());

    doc.Save("E:\\serialXML.xml");
}
 
Last edited by a moderator:
The code you posted here doesn't quite look like the code you posted in StackOverflow. Very likely it was because you didn't put your code here in code tags and so the forum software unfurled several of the URLs that you had in your code.
 
Anyway, look carefully at your code. Now look at the original code that copied. Why did you change these lines?
Your code:
C#:
    signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
    var idKeyInfo = "_" + Guid.NewGuid();
    var idKeyInfoProps = "_" + Guid.NewGuid() + signedPropsIdSuffix;

The original code:
C#:
    signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
    var idKeyInfo = "xmldsig-" + Guid.NewGuid();
    var idKeyInfoProps = "#xmldsig-" + Guid.NewGuid() + signedPropsIdSuffix;
    var idKeyInfoProps1 = "#xmldsig-" + Guid.NewGuid() + "-keyinfo";
 
I changed it because according to the rules it had to have an algorithm, SHA 256 bits and this one has three References, just like this example
C#:
<ds:SignatureMethod Algorithm="xmldsig-more namespace"></ds:SignatureMethod>
<ds:Reference Id="xmldsig-3c108bee-8a17-41e0-bcda-89e211245a80-ref0" URI="#CV1220719253095794000010100000003122542266060">
<ds:Transforms>
<ds:Transform Algorithm="XML-Signature Syntax and Processing"></ds:Transform>
<ds:Transform Algorithm="Canonical XML"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="XML Encryption Syntax and Processing"></ds:DigestMethod>
<ds:DigestValue>dkzHnURvh/AVO/EB9JF51hUMrKpSyHTun8KbBSA8nW8=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#xmldsig-3c108bee-8a17-41e0-bcda-89e211245a80-keyinfo">
<ds:Transforms>
<ds:Transform Algorithm="Canonical XML"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="XML Encryption Syntax and Processing"></ds:DigestMethod>
<ds:DigestValue>BPQAhALXCsJvkCsBGvffk6JE6/6SL2a2ly6rpJLs7T0=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="ELSIGN redirect" URI="#xmldsig-3c108bee-8a17-41e0-bcda-89e211245a80-signedprops">
<ds:Transforms>
<ds:Transform Algorithm="Canonical XML"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="XML Encryption Syntax and Processing"></ds:DigestMethod>
<ds:DigestValue>DIGaw4KpgrdxWwJ1gvTemwCc2pzolRakncXJuK2D7Kc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
 
Last edited by a moderator:
Again, please put code in code tags to not lose formatting or special symbols. I did it for you again, but it looks like it is too late.

Yes, but the original was SHA 256. Your code has SHA 1.

Additionally, that example has "#xmldigsig" prefixes for references. Your code is using "_" while the original had "#xmldigsig".
 
C#:
 static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
        {
            const string signedPropsIdSuffix = "-signedprops";

            var signedXml = new SignedXml(doc)
            {
                SigningKey = cert.GetRSAPrivateKey()
            };
            signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
            signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

            var idKeyInfo = "xmldsig-" + Guid.NewGuid();
            var idKeyInfoProps = "#xmldsig-" + Guid.NewGuid() + signedPropsIdSuffix;
            var idKeyInfoProps1 = "#xmldsig-" + Guid.NewGuid()+ "-keyinfo";

            #region keyinfo

            var keyInfo = new KeyInfo();
            var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
            keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
            keyInfo.AddClause(keydata);
            keyInfo.Id = idKeyInfo;
            signedXml.KeyInfo = keyInfo;

            #endregion keyinfo

            #region References

            //var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" };
            var transform = new XmlDsigExcC14NTransform();
            var references = new List<Reference>();

            // first reference
            var keyInfoReference = new Reference();
            keyInfoReference.Uri = "#" + keyInfo.Id;
            keyInfoReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
            keyInfoReference.AddTransform(transform);
            references.Add(keyInfoReference);

            //second reference
            var signaturePropertiesReference = new Reference();
            signaturePropertiesReference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";
            signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
            signaturePropertiesReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
            signaturePropertiesReference.AddTransform(transform);
            references.Add(signaturePropertiesReference);

            //third reference
            var documentReference = new Reference();
            documentReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
            // The code in the question didn't assign Uri, and since no transform did an inherent
            // node resolution, signing failed.
            documentReference.Uri = idKeyInfoProps1;
            documentReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            documentReference.AddTransform(transform);
            references.Add(documentReference);

            foreach (Reference reference in references)
            {
                signedXml.AddReference(reference);
            }

            #endregion

            #region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime

            var URI = "http://uri.etsi.org/01903/v1.3.2#";
            XmlElement qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);

            XmlElement signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
            signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);

            XmlElement SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
            XmlElement timestamp = doc.CreateElement("xades", "SigningTime", URI);
            timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");    // primero de la lista

            signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
            SignedSignatureProperties.AppendChild(timestamp);
            qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);

            var qualifyingPropertiesObject = new System.Security.Cryptography.Xml.DataObject
            {
                Data = qualifyingPropertiesRoot.SelectNodes("."),
                //Id = idKeyInfoProps
            };

            signedXml.AddObject(qualifyingPropertiesObject);
            #endregion

            SignedXml tmp = new SignedXml(doc)
            {
                SigningKey = signedXml.SigningKey,
                KeyInfo = signedXml.KeyInfo,
            };

            foreach (System.Security.Cryptography.Xml.DataObject obj in signedXml.Signature.ObjectList)
            {
                tmp.AddObject(obj);
            }

            tmp.AddReference(new Reference(""));
            tmp.ComputeSignature();

          

            XmlElement elem = tmp.GetXml();
            doc.DocumentElement.AppendChild(elem);
            Console.WriteLine("Stage 1 signed");
          
            

            signedXml.ComputeSignature();
            doc.DocumentElement.RemoveChild(elem);
            doc.DocumentElement.AppendChild(signedXml.GetXml());
          
            doc.Save("E:\\serialXML.xml");
        }
 
Thanks!

At this point, I don't know what else to try to look at. The only thing I can recommend is try to trim down the minimal amount of code to reproduce the problem.
 
third Reference, if you put empty in the URI, it signs but if you put Something of the Reference error poorly fortified.
 
if i put URI="#xmldsig-3bb686c0-cf09-4625-a91f-2f769047e857-keyinfo in third Reference is ok, but when I put URI="#xmldsig-3bb686c0-cf09-4625-a91f-2f769047e857-signedprops, how is it not recognizing -signedprops
 
Back
Top Bottom