title: How to create digitally signed Xml Message using standard ISO20022 in .net ( C# )?
body: <p>My project needs integration with payment gateway.
  The project is built in .net ( c# )
  To integrate the gateway i need to sign XML message digitally following ISO 20022 standard.
  I am using dot net library SignedXml of System.Security.Cryptography 
  The sample format and my code is shown below :</p>
  
  <p>Sample Code:</p>
  
  <pre><code>&lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
      &lt;ds:SignedInfo&gt;
          &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
          &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /&gt;
          &lt;ds:Reference URI=""&gt;
              &lt;ds:Transforms&gt;
                  &lt;ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&gt;
                  &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
              &lt;/ds:Transforms&gt;
              &lt;ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
              &lt;ds:DigestValue&gt;eoXljsKRVEUPMMqrqjdtHyIUD4GyjeIsGPx8vVLey9g=&lt;/ds:DigestValue&gt;
          &lt;/ds:Reference&gt;
          &lt;ds:Reference URI="#49e752ba-8e80-4be5-8538-67866c2e1dd9"&gt;
              &lt;ds:Transforms&gt;
                  &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
              &lt;/ds:Transforms&gt;
              &lt;ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
              &lt;ds:DigestValue&gt;n4pKHz5MvOPK7uDcdyFlxZrEz3kgtq6t56HcEdDmeyA=&lt;/ds:DigestValue&gt;
          &lt;/ds:Reference&gt;
          &lt;ds:Reference&gt;
              &lt;ds:Transforms&gt;
                  &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
              &lt;/ds:Transforms&gt;
              &lt;ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
              &lt;ds:DigestValue&gt;ZH7NiLE0HlL8nIChNnauUXYugxZlX6rgUI2YMSrzSyE=&lt;/ds:DigestValue&gt;
          &lt;/ds:Reference&gt;
      &lt;/ds:SignedInfo&gt;
      &lt;ds:SignatureValue&gt;
          KN6PPWZQ/C8AHexw+nqfX375S3rm4CyqjWxfzWcHGEpAfxE3j7RKArxq0Xx5ofnILJ0g5LlxKgNS
          YDJJ+HB/cc6S4LzWFFRbwL9U9fC8ZXNWk/Sf+4SSK/t/Aaz2TqYUDrpd4Q+qq8e+EMryI2sULRtC
          FxvBU/BRAAnnZhLBDQX3crSHU3ynaOSeicFbAaX1LuwCsKppqSZSFcq3MHgIQ4PBFFRlLtXVuQms
          I8ZYpSe2ZsxSlCwaSdNMXpQDunhbTQE464691W+kyBczVz37/jsCKy8q2AM5JA4sabHgMpO5NxsZ
          eK00sNKG+guRSTuMsZpdVaMZPjNI3aMxB+JHHw==
      &lt;/ds:SignatureValue&gt;
      &lt;ds:KeyInfo Id="49e752ba-8e80-4be5-8538-67866c2e1dd9"&gt;
          &lt;ds:X509Data&gt;
              &lt;ds:X509SKI&gt;
                  udATCnB3DNmvJuBuZCU/NCOAxU0=
              &lt;/ds:X509SKI&gt;
          &lt;/ds:X509Data&gt;
      &lt;/ds:KeyInfo&gt;
  &lt;/ds:Signature&gt;
  </code></pre>
  
  <p>My code : 
  When i try to run this adding reference with Unique Identifier, </p>
  
  <pre><code> Reference referenceKeyInfo = new Reference();
   referenceKeyInfo.Uri = "#"+keyInfo.Id;
  </code></pre>
  
  <p>I receive response as : <code>Malformed reference element</code> </p>
  
  <p>Also if someone can help me in how to create Reference without URI attribute?</p>
  
  <pre><code>        {
              //Access certificate
              X509Certificate2 cert = null;
  
              X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
              certStore.Open(OpenFlags.ReadOnly);
              X509Certificate2Collection certCollection = certStore.Certificates.Find(
                                         X509FindType.FindByThumbprint,
                                         "MY CERTIFICATE THUMBPRINT HERE",
                                         false);
              cert = certCollection[0];
  
  
  
              XmlDocument doc = new XmlDocument();
              XmlSerializer payloadserializer = new XmlSerializer(typeof(RequestPayload));
              var writer = new StringWriter();
              //serilize object to xml
              payloadserializer.Serialize(writer, requestPayload);
              string xml = writer.ToString();
              //load xml into XmlDocument
              doc.LoadXml(xml);
  
              //create object for xml signature and assign certificate private key to signature signing key
              SignedXml signedXml = new SignedXml(doc);
              signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
              /////Signature value
              signedXml.SigningKey = cert.PrivateKey;
  
              //create key info node of signature
              KeyInfo keyInfo = new KeyInfo();
              keyInfo.Id = Guid.NewGuid().ToString();//Id is uniq ID
              //// Reference Header element
  
              //create reference element of xml, for header and assign uri(default uri, uri="")
              Reference referenceHeader = new Reference();
              referenceHeader.Uri = "#header";
              referenceHeader.LoadXml(header);
              //create transofrm node for signature
              XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
              //done canonicalisation on transform and allows a signer to create a digest
              XmlDsigExcC14NTransform headerC14n = new XmlDsigExcC14NTransform();
              //add transform to reference node before digest algorithm
              referenceHeader.AddTransform(env);
              referenceHeader.AddTransform(headerC14n);
              signedXml.AddReference(referenceHeader);
  
              //create reference element of xml, for KeyInfo and uri with #document, which will be replace by uniqId
              Reference referenceKeyInfo = new Reference();
              referenceKeyInfo.Uri = "#"+keyInfo.Id;
              XmlDsigExcC14NTransform keyInfoC14n = new XmlDsigExcC14NTransform();
              referenceKeyInfo.AddTransform(keyInfoC14n);
              signedXml.AddReference(referenceKeyInfo);
  
              ////reference document element
              //create reference element of xml, for document and uri is absent            
              Reference referenceDocument = new Reference();           
              //done canonicalisation on transform and allows a signer to create a digest
              XmlDsigExcC14NTransform documentC14n = new XmlDsigExcC14NTransform();
              //add transform to reference node before digest algorithm
              referenceDocument.AddTransform(documentC14n);
              signedXml.AddReference(referenceDocument);
  
  
  
              ////KeyInfo element of signature
              // create KeyInfo element then create X509 element and add subject key id
              KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
              keyInfoData.AddSubjectKeyId("MY CERTIFICATE SUBJECT KEY ID HERE");
              keyInfo.AddClause(keyInfoData);
              signedXml.KeyInfo = keyInfo;
  
              // Compute the signature.
              signedXml.ComputeSignature();
  
              XmlElement xmlDigitalSignature = signedXml.GetXml();
              SetPrefix("ds", xmlDigitalSignature);
              string signatureXml = xmlDigitalSignature.OuterXml.ToString();
              requestPayload.AppHdr.Sgntr = signatureXml;
          }
  </code></pre>