By creating different types of programs, sometimes there is a problem to ensure the authenticity of the file. This situation occurs, when these files are very important data, change which could lead to generate different types of losses. Such files can be license files, containing financial data, and medical data, etc. This problem can be solved very easily using XML files. Just, sign that the XML file and check the signature before re-use file. If it is correct then we will have confidence, that the file has not been any unauthorized modifications. In the event of any change, signature of the document will not respond to the information, which appear in the document.

Signature of an XML document looks as follows:

<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">
  <SignedInfo>
    <CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" />
    <SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" />
    <Reference URI=\"\">
      <Transforms>
        <Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" />
      </Transforms>
      <DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />
      <DigestValue>QpLGfGqKiTKL+DmgkczmpbaOr8w=</DigestValue>
    </Reference>
  </SignedInfo>
  <SignatureValue>
     tWJ4EpN2mlbuor+TVqeTKh176sWVt7yu4ZppYOL9JJXkt+eYJVOy4k8sNvlecsfd5XzMkRcycUBtbO2QuJA0SeJjZHSggoIPUIZYANK6bJ+lQazNrgwvXgtLrGE5TE2hBnVorBvVcyUEs13wcVQ7V0QlnIDKMQ45n0T99XJUFeA=
  </SignatureValue>
  <KeyInfo>
    <KeyValue>
      <RSAKeyValue>
        <Modulus>
          v4/8/QokwB0w/weNGX+ClxH/Ajpmr9YcCIxyKN9rjhpN6P9ZENaJn3rGmEWwvuZf9Xf+QONrMp8yJ4FKbmWn2D/J/G8mzTwicWoaOgyhV+M6yYTUXlL6p/Rgw0XPsk++iY3y9A8pqa3AVyfgeqQDi85iqnMi981JHS+/o097qVU=
        </Modulus>
        <Exponent>AQAB</Exponent>
      </RSAKeyValue>
    </KeyValue>
  </KeyInfo>
</Signature&#91;/code&#93;
<p style="text-align: justify;">As you can see the signature consists of three blocks:</p>
<ul>
<li style="text-align: justify;">SignedInfo - additional information, which shall be signed,</li>
<li style="text-align: justify;">SignatureValue - the real value of signature,</li>
<li style="text-align: justify;">KeyInfo - stores the necessary information, that allow for validation of signatures.</li>
</ul>
<p style="text-align: justify;">To sign a document to perform a number of steps:</p>
<ol>
<li style="text-align: justify;">Create a key, which the document will be signed:
[code lang="csharp"]RSACryptoServiceProvider cryptoKey = new RSACryptoServiceProvider();
  • Prepare an object, which generates the signature of an XML document:
    1. Create an object:
      SignedXml signedXml = new SignedXml(xmlDocument);
    2. Make it a key, the XML document will be signed:
      signedXml.SigningKey = key;
    3. Add data, that will allow for verification of signatures:
      KeyInfo keyInfo = new KeyInfo();
      RSAKeyValue rsaKeyValue = new RSAKeyValue(key);
      keyInfo.AddClause(rsaKeyValue);
      signedXml.KeyInfo = keyInfo;
  • Create a reference to a document be signed:
    Reference reference = new Reference();
    reference.Uri = String.Empty;
    XmlDsigEnvelopedSignatureTransform envelopedSignatureTransform =
              new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(envelopedSignatureTransform);
    signedXml.AddReference(reference);
  • Calculate the signature of the document:
    signedXml.ComputeSignature();
  • Add a signature to a document be signed:
    XmlElement element = signedXml.GetXml();
    xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(element, true));
  • Using these steps we get a signed document. These steps can be summed up in one method, which will accept two parameters at the input:

    • XML document for signing,
    • key, which is to be signed document.

    The effect of this method will change the specified, XML document by adding his signature to. The code for this method looks like this:

    public static void SignXmlDocument(XmlDocument xmlDocument, RSA key)
      {
          if (xmlDocument == null)
          {
               throw new ArgumentNullException("xmlDocument");
          }
          if (key == null)
          {
               throw new ArgumentNullException("key");
          }
    
          SignedXml signedXml = new SignedXml(xmlDocument);
          signedXml.SigningKey = key;
          KeyInfo keyInfo = new KeyInfo();
          RSAKeyValue rsaKeyValue = new RSAKeyValue(key);
          keyInfo.AddClause(rsaKeyValue);
          signedXml.KeyInfo = keyInfo;
    
          Reference reference = new Reference();
          reference.Uri = String.Empty;
          XmlDsigEnvelopedSignatureTransform envelopedSignatureTransform =
                  new XmlDsigEnvelopedSignatureTransform();
          reference.AddTransform(envelopedSignatureTransform);
          signedXml.AddReference(reference);
          signedXml.ComputeSignature();
    
          XmlElement element = signedXml.GetXml();
          xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(element, true));
      }

    And finally, it is worth mentioning, that:

    • to sign the documents, you can use the same key several times. In this example, they are generated anew each time. But nothing precludes, to export them and use again,
    • for example, to generate a message digest function used is SHA-1, and to generate RSA signature algorithm. Nothing precludes, to use other solutions.
    • in the example to be signed document is added information allows the signature to verify the correctness. You can add this information is not, but then during the verification of an XML document must be given the missing information.